[
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n  - package-ecosystem: \"maven\"\n    directory: \"/common\"\n    schedule:\n      interval: \"weekly\"\n    groups:\n      dependencies:\n        applies-to: version-updates\n        patterns:\n          - \"*\"\n  - package-ecosystem: \"maven\"\n    directory: \"/factory\"\n    schedule:\n      interval: \"weekly\"\n    groups:\n      dependencies:\n        applies-to: version-updates\n        patterns:\n          - \"*\"\n  - package-ecosystem: \"maven\"\n    directory: \"/service\"\n    schedule:\n      interval: \"weekly\"\n    groups:\n      dependencies:\n        applies-to: version-updates\n        patterns:\n          - \"*\"\n  - package-ecosystem: \"maven\"\n    directory: \"/value\"\n    schedule:\n      interval: \"weekly\"\n    groups:\n      dependencies:\n        applies-to: version-updates\n        patterns:\n          - \"*\"\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"monthly\"\n    groups:\n      github-actions:\n        applies-to: version-updates\n        patterns:\n          - \"*\"\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n    branches:\n      - main\n\njobs:\n  test:\n    name: \"JDK ${{ matrix.java }}\"\n    strategy:\n      matrix:\n        java: [ 8, 11, 17 ]\n    runs-on: ubuntu-latest\n    steps:\n      # Cancel any previous runs for the same branch that are still running.\n      - name: 'Cancel previous runs'\n        uses: styfle/cancel-workflow-action@3155a141048f8f89c06b4cdae32e7853e97536bc\n        with:\n          access_token: ${{ github.token }}\n      - name: 'Check out repository'\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd\n      - name: 'Cache local Maven repository'\n        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306\n        with:\n          path: ~/.m2/repository\n          key: maven-${{ hashFiles('**/pom.xml') }}\n          restore-keys: |\n            maven-\n      - name: 'Set up JDK ${{ matrix.java }}'\n        uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654\n        with:\n          java-version: ${{ matrix.java }}\n          distribution: 'temurin'\n      - name: 'Install'\n        shell: bash\n        run: mvn -B dependency:go-offline test clean -U --quiet --fail-never -DskipTests=true -f build-pom.xml\n      - name: 'Test'\n        shell: bash\n        run: mvn -B verify -U --fail-at-end -Dsource.skip=true -Dmaven.javadoc.skip=true -f build-pom.xml\n\n  publish_snapshot:\n    name: 'Publish snapshot'\n    needs: test\n    if: github.event_name == 'push' && github.repository == 'google/auto'\n    runs-on: ubuntu-latest\n    steps:\n      - name: 'Check out repository'\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd\n      - name: 'Cache local Maven repository'\n        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306\n        with:\n          path: ~/.m2/repository\n          key: maven-${{ hashFiles('**/pom.xml') }}\n          restore-keys: |\n            maven-\n      - name: 'Set up JDK 11'\n        uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654\n        with:\n          java-version: 11\n          distribution: 'temurin'\n          server-id: central\n          server-username: CI_DEPLOY_USERNAME\n          server-password: CI_DEPLOY_PASSWORD\n      - name: 'Publish'\n        env:\n          CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }}\n          CI_DEPLOY_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }}\n        run: ./util/publish-snapshot-on-commit.sh\n\n  generate_docs:\n    permissions:\n      contents: write\n    name: 'Generate latest docs'\n    needs: test\n    if: github.event_name == 'push' && github.repository == 'google/auto'\n    runs-on: ubuntu-latest\n    steps:\n      - name: 'Check out repository'\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd\n      - name: 'Cache local Maven repository'\n        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306\n        with:\n          path: ~/.m2/repository\n          key: maven-${{ hashFiles('**/pom.xml') }}\n          restore-keys: |\n            maven-\n      - name: 'Set up JDK 17' # need 15+ to avoid https://bugs.openjdk.org/browse/JDK-8241780\n        uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654\n        with:\n          java-version: 17\n          distribution: 'temurin'\n      - name: 'Generate latest docs'\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        run: ./util/generate-latest-docs.sh\n"
  },
  {
    "path": ".gitignore",
    "content": ".classpath\n.factorypath\n.project\n.settings\neclipsebin\n\nbin\ngen\nbuild\nout\nlib\n\ntarget\n*.class\npom.xml.*\nrelease.properties\n\n.idea\n*.iml\nclasses\n\nobj\n\n.DS_Store\n*~\ndependency-reduced-pom.xml\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "Contributing\n============\n\nIf you would like to contribute code to Auto you can do so through GitHub\nby forking the repository and sending a pull request.\n\nWhen submitting code, please make every effort to follow existing conventions\nand style in order to keep the code as readable as possible.\n\nWhere appropriate, please provide unit tests or integration tests. Unit tests\nshould be JUnit based tests and can use either standard JUnit assertions or\nTruth assertions and be added to `<project>/src/test/java`.  Changes to\ncode generation or other build-time behaviour should go into small maven\nprojects using the `maven-invoker-plugin`.  Examples of this are in\n`generator/src/it` and can include bean-shell verification scripts and other\nfacilities provided by `maven-invoker-plugin`.\n\nPlease make sure your code compiles by running `mvn clean verify` which will\nexecute both unit and integration test phases.  Additionally, consider using\nhttp://travis-ci.org to validate your branches before you even put them into\npull requests.  All pull requests will be validated by Travis-ci in any case\nand must pass before being merged.\n\nIf you are adding or modifying files you may add your own copyright line, but\nplease ensure that the form is consistent with the existing files, and please\nnote that a Google, Inc. copyright line must appear in every copyright notice.\nAll files are released with the Apache 2.0 license and any new files may only\nbe accepted under the terms of that license.\n\nBefore your code can be accepted into the project you must sign the\n[Individual Contributor License Agreement (CLA)][1].\n\n\n [1]: https://developers.google.com/open-source/cla/individual\n"
  },
  {
    "path": "LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "# Auto\n\n[![Build Status](https://github.com/google/auto/actions/workflows/ci.yml/badge.svg)](https://github.com/google/auto/actions/workflows/ci.yml)\n\nA collection of source code generators for [Java][java].\n\n## Overview\n\n[Java][java] is full of code that is mechanical, repetitive, typically untested\nand sometimes the source of subtle bugs. _Sounds like a job for robots!_\n\nThe Auto subprojects are a collection of code generators that automate those\ntypes of tasks. They create the code you would have written, but without\nthe bugs.\n\nSave time.  Save code.  Save sanity.\n\n## Subprojects\n\n  * [AutoFactory] - JSR-330-compatible factories\n\n    [![Maven Central](https://img.shields.io/maven-central/v/com.google.auto.factory/auto-factory.svg)](https://mvnrepository.com/artifact/com.google.auto.factory/auto-factory)\n\n  * [AutoService] - Provider-configuration files for [`ServiceLoader`]\n\n    [![Maven Central](https://img.shields.io/maven-central/v/com.google.auto.service/auto-service.svg)](https://mvnrepository.com/artifact/com.google.auto.service/auto-service)\n\n  * [AutoValue] - Immutable [value-type] code generation for Java 8+.\n\n    [![Maven Central](https://img.shields.io/maven-central/v/com.google.auto.value/auto-value.svg)](https://mvnrepository.com/artifact/com.google.auto.value/auto-value)\n\n  * [Common] - Helper utilities for writing annotation processors.\n\n    [![Maven Central](https://img.shields.io/maven-central/v/com.google.auto/auto-common.svg)](https://mvnrepository.com/artifact/com.google.auto/auto-common)\n\n## License\n\n    Copyright 2013 Google LLC\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n\n[AutoFactory]: https://github.com/google/auto/tree/main/factory\n[AutoService]: https://github.com/google/auto/tree/main/service\n[AutoValue]: https://github.com/google/auto/tree/main/value\n[Common]: https://github.com/google/auto/tree/main/common\n\n[java]: https://en.wikipedia.org/wiki/Java_(programming_language)\n[value-type]: http://en.wikipedia.org/wiki/Value_object\n[`ServiceLoader`]: https://docs.oracle.com/en/java/javase/23/docs/api/java.base/java/util/ServiceLoader.html\n"
  },
  {
    "path": "build-pom.xml",
    "content": "<!-- A pure convenience for local builds and travis-ci. -->\n<project>\n  <modelVersion>4.0.0</modelVersion>\n  <groupId>build-only</groupId>\n  <artifactId>build-only</artifactId>\n  <version>NO_VERSION</version>\n  <packaging>pom</packaging>\n  <modules>\n    <module>common</module>\n    <module>factory</module>\n    <module>service</module>\n    <module>value</module>\n  </modules>\n  <distributionManagement>\n    <repository>\n      <id>sonatype-nexus-staging</id>\n      <name>Nexus Release Repository</name>\n      <url>file:///tmp/auto_project_maven_fake_repo/</url>\n    </repository>\n    <snapshotRepository>\n      <id>sonatype-nexus-snapshots</id>\n      <name>Sonatype Nexus Snapshots</name>\n      <url>file:///tmp/auto_project_maven_fake_repo/</url>\n    </snapshotRepository>\n  </distributionManagement>\n</project>\n"
  },
  {
    "path": "common/README.md",
    "content": "# Auto Common Utilities\n\n## Overview\n\nThe Auto project has a set of common utilities to help ease use of the\nannotation processing environment.\n\n## Utility classes of note\n\n`MoreTypes`\n:   Utilities and `Equivalence` wrappers for `TypeMirror` and related subtypes\n\n`MoreElements`\n:   Utilities for `Element` and related subtypes\n\n`SuperficialValidation`\n:   Very simple scanner to ensure an `Element` is valid and free from distortion\n    from upstream compilation errors\n\n`Visibility`\n:   Utilities for working with `Element`s' visibility levels (public, protected,\n    etc.)\n\n`BasicAnnotationProcessor`/`Step`\n:   Simple types that\n    -   implement a validating annotation processor\n    -   defer invalid elements until later\n    -   break processor actions into multiple steps (which may each handle\n        different annotations)\n\n## Usage/Setup\n\nAuto common utilities have a standard [Maven](http://maven.apache.org) setup\nwhich can also be used from Gradle, Ivy, Ant, or other systems which consume\nbinary artifacts from the central Maven binary artifact repositories.\n\n```xml\n<dependency>\n  <groupId>com.google.auto</groupId>\n  <artifactId>auto-common</artifactId>\n  <version>1.0-SNAPSHOT</version> <!-- or use a known release version -->\n</dependency>\n```\n"
  },
  {
    "path": "common/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Copyright 2014 Google LLC\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n-->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <groupId>com.google.auto</groupId>\n  <artifactId>auto-common</artifactId>\n  <version>HEAD-SNAPSHOT</version>\n  <name>Auto Common Libraries</name>\n  <description>\n    Common utilities for creating annotation processors.\n  </description>\n  <url>https://github.com/google/auto/tree/main/common</url>\n\n  <properties>\n    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n    <java.version>1.8</java.version>\n    <guava.version>33.5.0-jre</guava.version>\n    <truth.version>1.4.5</truth.version>\n  </properties>\n\n  <scm>\n    <url>http://github.com/google/auto</url>\n    <connection>scm:git:git://github.com/google/auto.git</connection>\n    <developerConnection>scm:git:ssh://git@github.com/google/auto.git</developerConnection>\n    <tag>HEAD</tag>\n  </scm>\n\n  <issueManagement>\n    <system>GitHub Issues</system>\n    <url>http://github.com/google/auto/issues</url>\n  </issueManagement>\n\n  <licenses>\n    <license>\n      <name>Apache 2.0</name>\n      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>\n    </license>\n  </licenses>\n\n  <organization>\n    <name>Google LLC</name>\n    <url>http://www.google.com</url>\n  </organization>\n\n  <dependencies>\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>guava</artifactId>\n      <version>${guava.version}</version>\n    </dependency>\n    <dependency>\n      <groupId>org.jspecify</groupId>\n      <artifactId>jspecify</artifactId>\n      <version>1.0.0</version>\n    </dependency>\n    <dependency>\n      <!-- Used only by GeneratedAnnotationSpecs.\n           If you use JavaPoet, you can use GeneratedAnnotationSpecs. -->\n      <groupId>com.squareup</groupId>\n      <artifactId>javapoet</artifactId>\n      <version>1.13.0</version>\n      <optional>true</optional>\n    </dependency>\n\n    <!-- test dependencies -->\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>guava-testlib</artifactId>\n      <version>${guava.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.testing.compile</groupId>\n      <artifactId>compile-testing</artifactId>\n      <version>0.23.0</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>junit</groupId>\n      <artifactId>junit</artifactId>\n      <version>4.13.2</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.truth</groupId>\n      <artifactId>truth</artifactId>\n      <version>${truth.version}</version>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <artifactId>maven-compiler-plugin</artifactId>\n        <version>3.15.0</version>\n        <configuration>\n          <source>${java.version}</source>\n          <target>${java.version}</target>\n          <compilerArgument>-Xlint:all</compilerArgument>\n          <showWarnings>true</showWarnings>\n          <showDeprecation>true</showDeprecation>\n          <testExcludes combine.children=\"append\" />\n        </configuration>\n      </plugin>\n      <plugin>\n        <artifactId>maven-jar-plugin</artifactId>\n        <version>3.5.0</version>\n      </plugin>\n      <plugin>\n        <artifactId>maven-javadoc-plugin</artifactId>\n        <version>3.12.0</version>\n        <executions>\n          <execution>\n            <id>attach-javadocs</id>\n            <goals>\n              <goal>jar</goal>\n            </goals>\n          </execution>\n        </executions>\n      </plugin>\n      <plugin>\n        <artifactId>maven-source-plugin</artifactId>\n        <version>3.4.0</version>\n        <executions>\n          <execution>\n            <id>attach-sources</id>\n            <goals>\n              <goal>jar-no-fork</goal>\n            </goals>\n          </execution>\n        </executions>\n      </plugin>\n      <plugin>\n        <groupId>org.sonatype.central</groupId>\n        <artifactId>central-publishing-maven-plugin</artifactId>\n        <version>0.10.0</version>\n        <extensions>true</extensions>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>test-with-ecj</id>\n      <activation>\n        <jdk>[17,)</jdk>\n      </activation>\n      <dependencies>\n        <!-- test dependencies -->\n        <dependency>\n          <groupId>org.eclipse.jdt</groupId>\n          <artifactId>ecj</artifactId>\n          <version>3.45.0</version>\n          <scope>test</scope>\n        </dependency>\n      </dependencies>\n    </profile>\n\n    <profile>\n      <id>test-without-ecj</id>\n      <activation>\n        <jdk>(,17)</jdk>\n      </activation>\n      <build>\n        <plugins>\n          <plugin>\n            <artifactId>maven-compiler-plugin</artifactId>\n            <configuration>\n              <testExcludes>\n                <exclude>**/OverridesTest.java</exclude>\n              </testExcludes>\n            </configuration>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n\n    <profile>\n      <id>sonatype-oss-release</id>\n      <build>\n        <plugins>\n          <plugin>\n            <artifactId>maven-gpg-plugin</artifactId>\n            <version>3.2.8</version>\n            <executions>\n              <execution>\n                <id>sign-artifacts</id>\n                <phase>verify</phase>\n                <goals>\n                  <goal>sign</goal>\n                </goals>\n              </execution>\n            </executions>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "common/src/main/java/com/google/auto/common/AnnotationMirrors.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport static com.google.auto.common.MoreElements.isAnnotationPresent;\nimport static com.google.common.base.Preconditions.checkNotNull;\nimport static com.google.common.collect.ImmutableSet.toImmutableSet;\nimport static java.util.Collections.unmodifiableMap;\n\nimport com.google.common.base.Equivalence;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport java.lang.annotation.Annotation;\nimport java.util.Arrays;\nimport java.util.Map;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.util.ElementFilter;\nimport javax.lang.model.util.Elements;\n\n/**\n * A utility class for working with {@link AnnotationMirror} instances.\n *\n * @author Gregory Kick\n */\npublic final class AnnotationMirrors {\n  private static final Equivalence<AnnotationMirror> ANNOTATION_MIRROR_EQUIVALENCE =\n      new Equivalence<AnnotationMirror>() {\n        @Override\n        protected boolean doEquivalent(AnnotationMirror left, AnnotationMirror right) {\n          return MoreTypes.equivalence()\n                  .equivalent(left.getAnnotationType(), right.getAnnotationType())\n              && AnnotationValues.equivalence()\n                  .pairwise()\n                  .equivalent(\n                      getAnnotationValuesWithDefaults(left).values(),\n                      getAnnotationValuesWithDefaults(right).values());\n        }\n\n        @Override\n        protected int doHash(AnnotationMirror annotation) {\n          DeclaredType type = annotation.getAnnotationType();\n          Iterable<AnnotationValue> annotationValues =\n              getAnnotationValuesWithDefaults(annotation).values();\n          return Arrays.hashCode(\n              new int[] {\n                MoreTypes.equivalence().hash(type),\n                AnnotationValues.equivalence().pairwise().hash(annotationValues)\n              });\n        }\n\n        @Override\n        public String toString() {\n          return \"AnnotationMirrors.equivalence()\";\n        }\n      };\n\n  /**\n   * Returns an {@link Equivalence} for {@link AnnotationMirror} as some implementations delegate\n   * equality tests to {@link Object#equals} whereas the documentation explicitly states that\n   * instance/reference equality is not the proper test.\n   */\n  public static Equivalence<AnnotationMirror> equivalence() {\n    return ANNOTATION_MIRROR_EQUIVALENCE;\n  }\n\n  /**\n   * Returns the {@link AnnotationMirror}'s map of {@link AnnotationValue} indexed by {@link\n   * ExecutableElement}, supplying default values from the annotation if the annotation property has\n   * not been set. This is equivalent to {@link\n   * Elements#getElementValuesWithDefaults(AnnotationMirror)} but can be called statically without\n   * an {@link Elements} instance.\n   *\n   * <p>The iteration order of elements of the returned map will be the order in which the {@link\n   * ExecutableElement}s are defined in {@code annotation}'s {@linkplain\n   * AnnotationMirror#getAnnotationType() type}.\n   */\n  public static ImmutableMap<ExecutableElement, AnnotationValue> getAnnotationValuesWithDefaults(\n      AnnotationMirror annotation) {\n    ImmutableMap.Builder<ExecutableElement, AnnotationValue> values = ImmutableMap.builder();\n    // Use unmodifiableMap to eliminate wildcards, which cause issues for our nullness checker.\n    @SuppressWarnings(\"GetElementValues\")\n    Map<ExecutableElement, AnnotationValue> declaredValues =\n        unmodifiableMap(annotation.getElementValues());\n    for (ExecutableElement method :\n        ElementFilter.methodsIn(annotation.getAnnotationType().asElement().getEnclosedElements())) {\n      // Must iterate and put in this order, to ensure consistency in generated code.\n      if (declaredValues.containsKey(method)) {\n        values.put(method, declaredValues.get(method));\n      } else if (method.getDefaultValue() != null) {\n        values.put(method, method.getDefaultValue());\n      } else {\n        throw new IllegalStateException(\n            \"Unset annotation value without default should never happen: \"\n                + MoreElements.asType(method.getEnclosingElement()).getQualifiedName()\n                + '.'\n                + method.getSimpleName()\n                + \"()\");\n      }\n    }\n    return values.build();\n  }\n\n  /**\n   * Returns an {@link AnnotationValue} for the named element if such an element was either declared\n   * in the usage represented by the provided {@link AnnotationMirror}, or if such an element was\n   * defined with a default.\n   *\n   * @throws IllegalArgumentException if no element is defined with the given elementName.\n   */\n  public static AnnotationValue getAnnotationValue(\n      AnnotationMirror annotationMirror, String elementName) {\n    return getAnnotationElementAndValue(annotationMirror, elementName).getValue();\n  }\n\n  /**\n   * Returns a {@link ExecutableElement} and its associated {@link AnnotationValue} if such an\n   * element was either declared in the usage represented by the provided {@link AnnotationMirror},\n   * or if such an element was defined with a default.\n   *\n   * @throws IllegalArgumentException if no element is defined with the given elementName.\n   */\n  public static Map.Entry<ExecutableElement, AnnotationValue> getAnnotationElementAndValue(\n      AnnotationMirror annotationMirror, final String elementName) {\n    checkNotNull(annotationMirror);\n    checkNotNull(elementName);\n    for (Map.Entry<ExecutableElement, AnnotationValue> entry :\n        getAnnotationValuesWithDefaults(annotationMirror).entrySet()) {\n      if (entry.getKey().getSimpleName().contentEquals(elementName)) {\n        return entry;\n      }\n    }\n    throw new IllegalArgumentException(\n        String.format(\n            \"@%s does not define an element %s()\",\n            MoreElements.asType(annotationMirror.getAnnotationType().asElement())\n                .getQualifiedName(),\n            elementName));\n  }\n\n  /**\n   * Returns all {@linkplain AnnotationMirror annotations} that are present on the given {@link\n   * Element} which are themselves annotated with {@code annotationClass}.\n   */\n  public static ImmutableSet<AnnotationMirror> getAnnotatedAnnotations(\n      Element element, Class<? extends Annotation> annotationClass) {\n    String name = annotationClass.getCanonicalName();\n    if (name == null) {\n      return ImmutableSet.of();\n    }\n    return getAnnotatedAnnotations(element, name);\n  }\n\n  /**\n   * Returns all {@linkplain AnnotationMirror annotations} that are present on the given {@link\n   * Element} which are themselves annotated with {@code annotation}.\n   */\n  public static ImmutableSet<AnnotationMirror> getAnnotatedAnnotations(\n      Element element, TypeElement annotation) {\n    return element.getAnnotationMirrors().stream()\n        .filter(input -> isAnnotationPresent(input.getAnnotationType().asElement(), annotation))\n        .collect(toImmutableSet());\n  }\n\n  /**\n   * Returns all {@linkplain AnnotationMirror annotations} that are present on the given {@link\n   * Element} which are themselves annotated with an annotation whose type's canonical name is\n   * {@code annotationName}.\n   */\n  public static ImmutableSet<AnnotationMirror> getAnnotatedAnnotations(\n      Element element, String annotationName) {\n    return element.getAnnotationMirrors().stream()\n        .filter(input -> isAnnotationPresent(input.getAnnotationType().asElement(), annotationName))\n        .collect(toImmutableSet());\n  }\n\n  /**\n   * Returns a string representation of the given annotation mirror, suitable for inclusion in a\n   * Java source file to reproduce the annotation in source form.\n   *\n   * <p>Fully qualified names are used for types in annotations, class literals, and enum constants,\n   * ensuring that the source form will compile without requiring additional imports.\n   */\n  public static String toString(AnnotationMirror annotationMirror) {\n    return AnnotationOutput.toString(annotationMirror);\n  }\n\n  private AnnotationMirrors() {}\n}\n"
  },
  {
    "path": "common/src/main/java/com/google/auto/common/AnnotationOutput.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport static com.google.auto.common.MoreTypes.asTypeElement;\n\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.Iterables;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.AnnotationValueVisitor;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.SimpleAnnotationValueVisitor8;\nimport org.jspecify.annotations.Nullable;\n\n/**\n * Handling of default values for annotation members.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\nfinal class AnnotationOutput {\n  private AnnotationOutput() {} // There are no instances of this class.\n\n  /**\n   * Visitor that produces a string representation of an annotation value, suitable for inclusion in\n   * a Java source file as an annotation member or as the initializer of a variable of the\n   * appropriate type. The syntax for the two is the same except for annotation members that are\n   * themselves annotations. Within an annotation, an annotation member can be written as\n   * {@code @NestedAnnotation(...)}, while in an initializer it must be written as an object, for\n   * example the construction of an {@code @AutoAnnotation} class. That's why we have this abstract\n   * class and two concrete subclasses.\n   */\n  private static class SourceFormVisitor\n      extends SimpleAnnotationValueVisitor8<@Nullable Void, StringBuilder> {\n\n    private String formatType(TypeMirror typeMirror) {\n      return asTypeElement(typeMirror).getQualifiedName().toString();\n    }\n\n    @Override\n    protected @Nullable Void defaultAction(Object value, StringBuilder sb) {\n      sb.append(value);\n      return null;\n    }\n\n    @Override\n    public @Nullable Void visitArray(List<? extends AnnotationValue> values, StringBuilder sb) {\n      sb.append('{');\n      String sep = \"\";\n      for (AnnotationValue value : values) {\n        sb.append(sep);\n        visit(value, sb);\n        sep = \", \";\n      }\n      sb.append('}');\n      return null;\n    }\n\n    @Override\n    public @Nullable Void visitByte(byte b, StringBuilder sb) {\n      sb.append(\"(byte) \").append(b);\n      return null;\n    }\n\n    @Override\n    public @Nullable Void visitShort(short s, StringBuilder sb) {\n      sb.append(\"(short) \").append(s);\n      return null;\n    }\n\n    @Override\n    public @Nullable Void visitChar(char c, StringBuilder sb) {\n      appendQuoted(sb, c);\n      return null;\n    }\n\n    @Override\n    public @Nullable Void visitLong(long i, StringBuilder sb) {\n      sb.append(i).append('L');\n      return null;\n    }\n\n    @Override\n    public @Nullable Void visitDouble(double d, StringBuilder sb) {\n      if (Double.isNaN(d)) {\n        sb.append(\"Double.NaN\");\n      } else if (d == Double.POSITIVE_INFINITY) {\n        sb.append(\"Double.POSITIVE_INFINITY\");\n      } else if (d == Double.NEGATIVE_INFINITY) {\n        sb.append(\"Double.NEGATIVE_INFINITY\");\n      } else {\n        sb.append(d);\n      }\n      return null;\n    }\n\n    @Override\n    public @Nullable Void visitFloat(float f, StringBuilder sb) {\n      if (Float.isNaN(f)) {\n        sb.append(\"Float.NaN\");\n      } else if (f == Float.POSITIVE_INFINITY) {\n        sb.append(\"Float.POSITIVE_INFINITY\");\n      } else if (f == Float.NEGATIVE_INFINITY) {\n        sb.append(\"Float.NEGATIVE_INFINITY\");\n      } else {\n        sb.append(f).append('F');\n      }\n      return null;\n    }\n\n    @Override\n    public @Nullable Void visitEnumConstant(VariableElement c, StringBuilder sb) {\n      sb.append(formatType(c.asType())).append('.').append(c.getSimpleName());\n      return null;\n    }\n\n    @Override\n    public @Nullable Void visitString(String s, StringBuilder sb) {\n      appendQuoted(sb, s);\n      return null;\n    }\n\n    @Override\n    public @Nullable Void visitType(TypeMirror classConstant, StringBuilder sb) {\n      sb.append(formatType(classConstant)).append(\".class\");\n      return null;\n    }\n\n    @Override\n    public @Nullable Void visitAnnotation(AnnotationMirror a, StringBuilder sb) {\n      sb.append('@').append(formatType(a.getAnnotationType()));\n      ImmutableMap<ExecutableElement, AnnotationValue> map =\n          ImmutableMap.copyOf(a.getElementValues());\n      if (!map.isEmpty()) {\n        sb.append('(');\n        Optional<AnnotationValue> shortForm = shortForm(map);\n        if (shortForm.isPresent()) {\n          this.visit(maybeShorten(shortForm.get()), sb);\n        } else {\n          String sep = \"\";\n          for (Map.Entry<ExecutableElement, AnnotationValue> entry : map.entrySet()) {\n            sb.append(sep).append(entry.getKey().getSimpleName()).append(\" = \");\n            sep = \", \";\n            this.visit(maybeShorten(entry.getValue()), sb);\n          }\n        }\n        sb.append(')');\n      }\n      return null;\n    }\n  }\n\n  private static AnnotationValue maybeShorten(AnnotationValue value) {\n    return ARRAY_VISITOR.visit(value, value);\n  }\n\n  private static final AnnotationValueVisitor<AnnotationValue, AnnotationValue> ARRAY_VISITOR =\n      new SimpleAnnotationValueVisitor8<AnnotationValue, AnnotationValue>() {\n        @Override\n        public AnnotationValue visitArray(\n            List<? extends AnnotationValue> values, AnnotationValue input) {\n          if (values.size() == 1) {\n            // We can shorten @Foo(a = {23}) to @Foo(a = 23). For the specific case where `a` is\n            // actually `value`, we'll already have shortened that in visitAnnotation, so\n            // effectively we go from @Foo(value = {23}) to @Foo({23}) to @Foo(23).\n            return Iterables.getOnlyElement(values);\n          }\n          return input;\n        }\n\n        @Override\n        protected AnnotationValue defaultAction(Object o, AnnotationValue input) {\n          return input;\n        }\n      };\n\n  // We can shorten @Annot(value = 23) to @Annot(23).\n  private static Optional<AnnotationValue> shortForm(\n      Map<ExecutableElement, AnnotationValue> values) {\n    if (values.size() == 1\n        && Iterables.getOnlyElement(values.keySet()).getSimpleName().contentEquals(\"value\")) {\n      return Optional.of(Iterables.getOnlyElement(values.values()));\n    }\n    return Optional.empty();\n  }\n\n  /**\n   * Returns a string representation of the given annotation value, suitable for inclusion in a Java\n   * source file as the initializer of a variable of the appropriate type.\n   */\n  static String toString(AnnotationValue annotationValue) {\n    StringBuilder sb = new StringBuilder();\n    new SourceFormVisitor().visit(annotationValue, sb);\n    return sb.toString();\n  }\n\n  /**\n   * Returns a string representation of the given annotation mirror, suitable for inclusion in a\n   * Java source file to reproduce the annotation in source form.\n   */\n  static String toString(AnnotationMirror annotationMirror) {\n    StringBuilder sb = new StringBuilder();\n    new SourceFormVisitor().visitAnnotation(annotationMirror, sb);\n    return sb.toString();\n  }\n\n  private static StringBuilder appendQuoted(StringBuilder sb, String s) {\n    sb.append('\"');\n    for (int i = 0; i < s.length(); i++) {\n      appendEscaped(sb, s.charAt(i));\n    }\n    return sb.append('\"');\n  }\n\n  private static StringBuilder appendQuoted(StringBuilder sb, char c) {\n    sb.append('\\'');\n    appendEscaped(sb, c);\n    return sb.append('\\'');\n  }\n\n  private static void appendEscaped(StringBuilder sb, char c) {\n    switch (c) {\n      case '\\\\':\n      case '\"':\n      case '\\'':\n        sb.append('\\\\').append(c);\n        break;\n      case '\\n':\n        sb.append(\"\\\\n\");\n        break;\n      case '\\r':\n        sb.append(\"\\\\r\");\n        break;\n      case '\\t':\n        sb.append(\"\\\\t\");\n        break;\n      default:\n        if (c < 0x20) {\n          sb.append(String.format(\"\\\\%03o\", (int) c));\n        } else if (c < 0x7f || Character.isLetter(c)) {\n          sb.append(c);\n        } else {\n          sb.append(String.format(\"\\\\u%04x\", (int) c));\n        }\n        break;\n    }\n  }\n}\n"
  },
  {
    "path": "common/src/main/java/com/google/auto/common/AnnotationValues.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport static com.google.common.base.Preconditions.checkNotNull;\nimport static com.google.common.collect.ImmutableList.toImmutableList;\n\nimport com.google.common.base.Equivalence;\nimport com.google.common.collect.ImmutableList;\nimport java.util.List;\nimport java.util.function.Function;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.SimpleAnnotationValueVisitor8;\n\n/**\n * A utility class for working with {@link AnnotationValue} instances.\n *\n * @author Christian Gruber\n */\npublic final class AnnotationValues {\n  private static final Equivalence<AnnotationValue> ANNOTATION_VALUE_EQUIVALENCE =\n      new Equivalence<AnnotationValue>() {\n        @Override\n        protected boolean doEquivalent(AnnotationValue left, AnnotationValue right) {\n          return left.accept(\n              new SimpleAnnotationValueVisitor8<Boolean, AnnotationValue>() {\n                // LHS is not an annotation or array of annotation values, so just test equality.\n                @Override\n                protected Boolean defaultAction(Object left, AnnotationValue right) {\n                  return left.equals(\n                      right.accept(\n                          new SimpleAnnotationValueVisitor8<Object, Void>() {\n                            @Override\n                            protected Object defaultAction(Object object, Void unused) {\n                              return object;\n                            }\n                          },\n                          null));\n                }\n\n                // LHS is an annotation mirror so test equivalence for RHS annotation mirrors\n                // and false for other types.\n                @Override\n                public Boolean visitAnnotation(AnnotationMirror left, AnnotationValue right) {\n                  return right.accept(\n                      new SimpleAnnotationValueVisitor8<Boolean, AnnotationMirror>() {\n                        @Override\n                        protected Boolean defaultAction(Object right, AnnotationMirror left) {\n                          return false; // Not an annotation mirror, so can't be equal to such.\n                        }\n\n                        @Override\n                        public Boolean visitAnnotation(\n                            AnnotationMirror right, AnnotationMirror left) {\n                          return AnnotationMirrors.equivalence().equivalent(left, right);\n                        }\n                      },\n                      left);\n                }\n\n                // LHS is a list of annotation values have to collect-test equivalences, or false\n                // for any other types.\n                @Override\n                public Boolean visitArray(\n                    List<? extends AnnotationValue> left, AnnotationValue right) {\n                  return right.accept(\n                      new SimpleAnnotationValueVisitor8<\n                          Boolean, List<? extends AnnotationValue>>() {\n                        @Override\n                        protected Boolean defaultAction(\n                            Object ignored, List<? extends AnnotationValue> alsoIgnored) {\n                          return false; // Not an array, so can't be equal to such.\n                        }\n\n                        @SuppressWarnings(\"unchecked\") // safe covariant cast\n                        @Override\n                        public Boolean visitArray(\n                            List<? extends AnnotationValue> right,\n                            List<? extends AnnotationValue> left) {\n                          return AnnotationValues.equivalence()\n                              .pairwise()\n                              .equivalent(\n                                  (List<AnnotationValue>) left, (List<AnnotationValue>) right);\n                        }\n                      },\n                      left);\n                }\n\n                @Override\n                public Boolean visitType(TypeMirror left, AnnotationValue right) {\n                  return right.accept(\n                      new SimpleAnnotationValueVisitor8<Boolean, TypeMirror>() {\n                        @Override\n                        protected Boolean defaultAction(Object ignored, TypeMirror alsoIgnored) {\n                          return false; // Not an annotation mirror, so can't be equal to such.\n                        }\n\n                        @Override\n                        public Boolean visitType(TypeMirror right, TypeMirror left) {\n                          return MoreTypes.equivalence().equivalent(left, right);\n                        }\n                      },\n                      left);\n                }\n              },\n              right);\n        }\n\n        @Override\n        protected int doHash(AnnotationValue value) {\n          return value.accept(\n              new SimpleAnnotationValueVisitor8<Integer, Void>() {\n                @Override\n                public Integer visitAnnotation(AnnotationMirror value, Void ignore) {\n                  return AnnotationMirrors.equivalence().hash(value);\n                }\n\n                @SuppressWarnings(\"unchecked\") // safe covariant cast\n                @Override\n                public Integer visitArray(List<? extends AnnotationValue> values, Void ignore) {\n                  return AnnotationValues.equivalence()\n                      .pairwise()\n                      .hash((List<AnnotationValue>) values);\n                }\n\n                @Override\n                public Integer visitType(TypeMirror value, Void ignore) {\n                  return MoreTypes.equivalence().hash(value);\n                }\n\n                @Override\n                protected Integer defaultAction(Object value, Void ignored) {\n                  return value.hashCode();\n                }\n              },\n              null);\n        }\n\n        @Override\n        public String toString() {\n          return \"AnnotationValues.equivalence()\";\n        }\n      };\n\n  /**\n   * Returns an {@link Equivalence} for {@link AnnotationValue} as annotation values may contain\n   * {@link AnnotationMirror} instances some of whose implementations delegate equality tests to\n   * {@link Object#equals} whereas the documentation explicitly states that instance/reference\n   * equality is not the proper test.\n   *\n   * @see AnnotationMirrors#equivalence()\n   */\n  public static Equivalence<AnnotationValue> equivalence() {\n    return ANNOTATION_VALUE_EQUIVALENCE;\n  }\n\n  private static class DefaultVisitor<T> extends SimpleAnnotationValueVisitor8<T, Void> {\n    final Class<T> clazz;\n\n    DefaultVisitor(Class<T> clazz) {\n      this.clazz = checkNotNull(clazz);\n    }\n\n    @Override\n    public T defaultAction(Object o, Void unused) {\n      throw new IllegalArgumentException(\n          \"Expected a \" + clazz.getSimpleName() + \", got instead: \" + o);\n    }\n  }\n\n  private static final class TypeMirrorVisitor extends DefaultVisitor<DeclaredType> {\n    static final TypeMirrorVisitor INSTANCE = new TypeMirrorVisitor();\n\n    TypeMirrorVisitor() {\n      super(DeclaredType.class);\n    }\n\n    @Override\n    public DeclaredType visitType(TypeMirror value, Void unused) {\n      return MoreTypes.asDeclared(value);\n    }\n  }\n  ;\n\n  /**\n   * Returns the value as a class.\n   *\n   * @throws IllegalArgumentException if the value is not a class.\n   */\n  public static DeclaredType getTypeMirror(AnnotationValue value) {\n    return TypeMirrorVisitor.INSTANCE.visit(value);\n  }\n\n  private static final class AnnotationMirrorVisitor extends DefaultVisitor<AnnotationMirror> {\n    static final AnnotationMirrorVisitor INSTANCE = new AnnotationMirrorVisitor();\n\n    AnnotationMirrorVisitor() {\n      super(AnnotationMirror.class);\n    }\n\n    @Override\n    public AnnotationMirror visitAnnotation(AnnotationMirror value, Void unused) {\n      return value;\n    }\n  }\n  ;\n\n  /**\n   * Returns the value as an AnnotationMirror.\n   *\n   * @throws IllegalArgumentException if the value is not an annotation.\n   */\n  public static AnnotationMirror getAnnotationMirror(AnnotationValue value) {\n    return AnnotationMirrorVisitor.INSTANCE.visit(value);\n  }\n\n  private static final class EnumVisitor extends DefaultVisitor<VariableElement> {\n    static final EnumVisitor INSTANCE = new EnumVisitor();\n\n    EnumVisitor() {\n      super(VariableElement.class);\n    }\n\n    @Override\n    public VariableElement visitEnumConstant(VariableElement value, Void unused) {\n      return value;\n    }\n  }\n\n  /**\n   * Returns the value as a VariableElement.\n   *\n   * @throws IllegalArgumentException if the value is not an enum.\n   */\n  public static VariableElement getEnum(AnnotationValue value) {\n    return EnumVisitor.INSTANCE.visit(value);\n  }\n\n  private static <T> T valueOfType(AnnotationValue annotationValue, Class<T> type) {\n    Object value = annotationValue.getValue();\n    if (!type.isInstance(value)) {\n      throw new IllegalArgumentException(\n          \"Expected \" + type.getSimpleName() + \", got instead: \" + value);\n    }\n    return type.cast(value);\n  }\n\n  /**\n   * Returns the value as a string.\n   *\n   * @throws IllegalArgumentException if the value is not a string.\n   */\n  public static String getString(AnnotationValue value) {\n    return valueOfType(value, String.class);\n  }\n\n  /**\n   * Returns the value as an int.\n   *\n   * @throws IllegalArgumentException if the value is not an int.\n   */\n  public static int getInt(AnnotationValue value) {\n    return valueOfType(value, Integer.class);\n  }\n\n  /**\n   * Returns the value as a long.\n   *\n   * @throws IllegalArgumentException if the value is not a long.\n   */\n  public static long getLong(AnnotationValue value) {\n    return valueOfType(value, Long.class);\n  }\n\n  /**\n   * Returns the value as a byte.\n   *\n   * @throws IllegalArgumentException if the value is not a byte.\n   */\n  public static byte getByte(AnnotationValue value) {\n    return valueOfType(value, Byte.class);\n  }\n\n  /**\n   * Returns the value as a short.\n   *\n   * @throws IllegalArgumentException if the value is not a short.\n   */\n  public static short getShort(AnnotationValue value) {\n    return valueOfType(value, Short.class);\n  }\n\n  /**\n   * Returns the value as a float.\n   *\n   * @throws IllegalArgumentException if the value is not a float.\n   */\n  public static float getFloat(AnnotationValue value) {\n    return valueOfType(value, Float.class);\n  }\n\n  /**\n   * Returns the value as a double.\n   *\n   * @throws IllegalArgumentException if the value is not a double.\n   */\n  public static double getDouble(AnnotationValue value) {\n    return valueOfType(value, Double.class);\n  }\n\n  /**\n   * Returns the value as a boolean.\n   *\n   * @throws IllegalArgumentException if the value is not a boolean.\n   */\n  public static boolean getBoolean(AnnotationValue value) {\n    return valueOfType(value, Boolean.class);\n  }\n\n  /**\n   * Returns the value as a char.\n   *\n   * @throws IllegalArgumentException if the value is not a char.\n   */\n  public static char getChar(AnnotationValue value) {\n    return valueOfType(value, Character.class);\n  }\n\n  private static final class ArrayVisitor<T>\n      extends SimpleAnnotationValueVisitor8<ImmutableList<T>, Void> {\n    final Function<AnnotationValue, T> visitT;\n\n    ArrayVisitor(Function<AnnotationValue, T> visitT) {\n      this.visitT = checkNotNull(visitT);\n    }\n\n    @Override\n    public ImmutableList<T> defaultAction(Object o, Void unused) {\n      throw new IllegalArgumentException(\"Expected an array, got instead: \" + o);\n    }\n\n    @Override\n    public ImmutableList<T> visitArray(List<? extends AnnotationValue> values, Void unused) {\n      return values.stream().map(visitT).collect(toImmutableList());\n    }\n  }\n\n  private static final ArrayVisitor<DeclaredType> TYPE_MIRRORS_VISITOR =\n      new ArrayVisitor<>(AnnotationValues::getTypeMirror);\n\n  /**\n   * Returns the value as a list of classes.\n   *\n   * @throws IllegalArgumentException if the value is not an array of classes.\n   */\n  public static ImmutableList<DeclaredType> getTypeMirrors(AnnotationValue value) {\n    return TYPE_MIRRORS_VISITOR.visit(value);\n  }\n\n  private static final ArrayVisitor<AnnotationMirror> ANNOTATION_MIRRORS_VISITOR =\n      new ArrayVisitor<>(AnnotationValues::getAnnotationMirror);\n\n  /**\n   * Returns the value as a list of annotations.\n   *\n   * @throws IllegalArgumentException if the value if not an array of annotations.\n   */\n  public static ImmutableList<AnnotationMirror> getAnnotationMirrors(AnnotationValue value) {\n    return ANNOTATION_MIRRORS_VISITOR.visit(value);\n  }\n\n  private static final ArrayVisitor<VariableElement> ENUMS_VISITOR =\n      new ArrayVisitor<>(AnnotationValues::getEnum);\n\n  /**\n   * Returns the value as a list of enums.\n   *\n   * @throws IllegalArgumentException if the value is not an array of enums.\n   */\n  public static ImmutableList<VariableElement> getEnums(AnnotationValue value) {\n    return ENUMS_VISITOR.visit(value);\n  }\n\n  private static final ArrayVisitor<String> STRINGS_VISITOR =\n      new ArrayVisitor<>(AnnotationValues::getString);\n\n  /**\n   * Returns the value as a list of strings.\n   *\n   * @throws IllegalArgumentException if the value is not an array of strings.\n   */\n  public static ImmutableList<String> getStrings(AnnotationValue value) {\n    return STRINGS_VISITOR.visit(value);\n  }\n\n  private static final ArrayVisitor<Integer> INTS_VISITOR =\n      new ArrayVisitor<>(AnnotationValues::getInt);\n\n  /**\n   * Returns the value as a list of integers.\n   *\n   * @throws IllegalArgumentException if the value is not an array of ints.\n   */\n  public static ImmutableList<Integer> getInts(AnnotationValue value) {\n    return INTS_VISITOR.visit(value);\n  }\n\n  private static final ArrayVisitor<Long> LONGS_VISITOR =\n      new ArrayVisitor<>(AnnotationValues::getLong);\n\n  /**\n   * Returns the value as a list of longs.\n   *\n   * @throws IllegalArgumentException if the value is not an array of longs.\n   */\n  public static ImmutableList<Long> getLongs(AnnotationValue value) {\n    return LONGS_VISITOR.visit(value);\n  }\n\n  private static final ArrayVisitor<Byte> BYTES_VISITOR =\n      new ArrayVisitor<>(AnnotationValues::getByte);\n\n  /**\n   * Returns the value as a list of bytes.\n   *\n   * @throws IllegalArgumentException if the value is not an array of bytes.\n   */\n  public static ImmutableList<Byte> getBytes(AnnotationValue value) {\n    return BYTES_VISITOR.visit(value);\n  }\n\n  private static final ArrayVisitor<Short> SHORTS_VISITOR =\n      new ArrayVisitor<>(AnnotationValues::getShort);\n\n  /**\n   * Returns the value as a list of shorts.\n   *\n   * @throws IllegalArgumentException if the value is not an array of shorts.\n   */\n  public static ImmutableList<Short> getShorts(AnnotationValue value) {\n    return SHORTS_VISITOR.visit(value);\n  }\n\n  private static final ArrayVisitor<Float> FLOATS_VISITOR =\n      new ArrayVisitor<>(AnnotationValues::getFloat);\n\n  /**\n   * Returns the value as a list of floats.\n   *\n   * @throws IllegalArgumentException if the value is not an array of floats.\n   */\n  public static ImmutableList<Float> getFloats(AnnotationValue value) {\n    return FLOATS_VISITOR.visit(value);\n  }\n\n  private static final ArrayVisitor<Double> DOUBLES_VISITOR =\n      new ArrayVisitor<>(AnnotationValues::getDouble);\n\n  /**\n   * Returns the value as a list of doubles.\n   *\n   * @throws IllegalArgumentException if the value is not an array of doubles.\n   */\n  public static ImmutableList<Double> getDoubles(AnnotationValue value) {\n    return DOUBLES_VISITOR.visit(value);\n  }\n\n  private static final ArrayVisitor<Boolean> BOOLEANS_VISITOR =\n      new ArrayVisitor<>(AnnotationValues::getBoolean);\n\n  /**\n   * Returns the value as a list of booleans.\n   *\n   * @throws IllegalArgumentException if the value is not an array of booleans.\n   */\n  public static ImmutableList<Boolean> getBooleans(AnnotationValue value) {\n    return BOOLEANS_VISITOR.visit(value);\n  }\n\n  private static final ArrayVisitor<Character> CHARS_VISITOR =\n      new ArrayVisitor<>(AnnotationValues::getChar);\n\n  /**\n   * Returns the value as a list of characters.\n   *\n   * @throws IllegalArgumentException if the value is not an array of chars.\n   */\n  public static ImmutableList<Character> getChars(AnnotationValue value) {\n    return CHARS_VISITOR.visit(value);\n  }\n\n  private static final ArrayVisitor<AnnotationValue> ANNOTATION_VALUES_VISITOR =\n      new ArrayVisitor<>(x -> x);\n\n  /**\n   * Returns the value as a list of {@link AnnotationValue}s.\n   *\n   * @throws IllegalArgumentException if the value is not an array.\n   */\n  public static ImmutableList<AnnotationValue> getAnnotationValues(AnnotationValue value) {\n    return ANNOTATION_VALUES_VISITOR.visit(value);\n  }\n\n  /**\n   * Returns a string representation of the given annotation value, suitable for inclusion in a Java\n   * source file as part of an annotation. For example, if {@code annotationValue} represents the\n   * string {@code unchecked} in the annotation {@code @SuppressWarnings(\"unchecked\")}, this method\n   * will return the string {@code \"unchecked\"}, which you can then use as part of an annotation\n   * being generated.\n   *\n   * <p>For all annotation values other than nested annotations, the returned string can also be\n   * used to initialize a variable of the appropriate type.\n   *\n   * <p>Fully qualified names are used for types in annotations, class literals, and enum constants,\n   * ensuring that the source form will compile without requiring additional imports.\n   */\n  public static String toString(AnnotationValue annotationValue) {\n    return AnnotationOutput.toString(annotationValue);\n  }\n\n  private AnnotationValues() {}\n}\n"
  },
  {
    "path": "common/src/main/java/com/google/auto/common/BasicAnnotationProcessor.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport static com.google.auto.common.MoreElements.asExecutable;\nimport static com.google.auto.common.MoreElements.asType;\nimport static com.google.auto.common.MoreElements.isAnnotationPresent;\nimport static com.google.auto.common.MoreElements.isType;\nimport static com.google.auto.common.SuperficialValidation.validateElement;\nimport static com.google.common.base.Preconditions.checkState;\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static com.google.common.collect.ImmutableMap.toImmutableMap;\nimport static com.google.common.collect.ImmutableSet.toImmutableSet;\nimport static com.google.common.collect.MoreCollectors.onlyElement;\nimport static com.google.common.collect.Multimaps.filterKeys;\nimport static java.util.Objects.requireNonNull;\nimport static javax.lang.model.element.ElementKind.CONSTRUCTOR;\nimport static javax.lang.model.element.ElementKind.METHOD;\nimport static javax.lang.model.element.ElementKind.PACKAGE;\nimport static javax.tools.Diagnostic.Kind.ERROR;\nimport static javax.tools.Diagnostic.Kind.WARNING;\n\nimport com.google.common.base.Ascii;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.ImmutableSetMultimap;\nimport com.google.common.collect.Iterables;\nimport com.google.common.collect.LinkedHashMultimap;\nimport com.google.common.collect.SetMultimap;\nimport com.google.common.collect.Sets;\nimport java.lang.annotation.Annotation;\nimport java.util.LinkedHashSet;\nimport java.util.Objects;\nimport java.util.Set;\nimport javax.annotation.processing.AbstractProcessor;\nimport javax.annotation.processing.Messager;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.annotation.processing.RoundEnvironment;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ElementKind;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.Name;\nimport javax.lang.model.element.PackageElement;\nimport javax.lang.model.element.Parameterizable;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.TypeParameterElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.util.Elements;\nimport org.jspecify.annotations.Nullable;\n\n/**\n * An abstract {@link javax.annotation.processing.Processor Processor} implementation that defers\n * processing of {@link Element}s to later rounds if they cannot be processed.\n *\n * <p>Subclasses put their processing logic in {@link Step} implementations. The steps are passed to\n * the processor by returning them in the {@link #steps()} method, and can access the {@link\n * ProcessingEnvironment} using {@link #processingEnv}.\n *\n * <p>Any logic that needs to happen once per round can be specified by overriding {@link\n * #postRound(RoundEnvironment)}.\n *\n * <h2>Ill-formed elements are deferred</h2>\n *\n * Any annotated element whose nearest enclosing type is not well-formed is deferred, and not passed\n * to any {@code Step}. This helps processors to avoid many common pitfalls, such as {@link\n * javax.lang.model.type.ErrorType ErrorType} instances, {@link ClassCastException}s and badly\n * coerced types.\n *\n * <p>A non-package element is considered well-formed if its type, type parameters, parameters,\n * default values, supertypes, annotations, and enclosed elements are. Package elements are treated\n * similarly, except that their enclosed elements are not validated. See {@link\n * SuperficialValidation#validateElement(Element)} for details.\n *\n * <p>The primary disadvantage to this validation is that any element that forms a circular\n * dependency with a type generated by another {@code BasicAnnotationProcessor} will never compile\n * because the element will never be fully complete. All such compilations will fail with an error\n * message on the offending type that describes the issue.\n *\n * <h2>Each {@code Step} can defer elements</h2>\n *\n * <p>Each {@code Step} can defer elements by including them in the set returned by {@link\n * Step#process(ImmutableSetMultimap)}; elements deferred by a step will be passed back to that step\n * in a later round of processing.\n *\n * <p>This feature is useful when one processor may depend on code generated by another, independent\n * processor, in a way that isn't caught by the well-formedness check described above. For example,\n * if an element {@code A} cannot be processed because processing it depends on the existence of\n * some class {@code B}, then {@code A} should be deferred until a later round of processing, when\n * {@code B} will have been generated by another processor.\n *\n * <p>If {@code A} directly references {@code B}, then the well-formedness check will correctly\n * defer processing of {@code A} until {@code B} has been generated.\n *\n * <p>However, if {@code A} references {@code B} only indirectly (for example, from within a method\n * body), then the well-formedness check will not defer processing {@code A}, but a processing step\n * can reject {@code A}.\n */\npublic abstract class BasicAnnotationProcessor extends AbstractProcessor {\n\n  /* For every element that is not module/package, to be well-formed its\n   * enclosing-type in its entirety should be well-formed. Since modules\n   * don't get annotated (and are not supported here) they can be ignored.\n   */\n\n  /**\n   * Packages and types that have been deferred because either they themselves reference\n   * as-yet-undefined types, or at least one of their contained elements does.\n   */\n  private final Set<ElementFactory> deferredEnclosingElements = new LinkedHashSet<>();\n\n  /**\n   * Elements that were explicitly deferred in some {@link Step} by being returned from {@link\n   * Step#process}.\n   */\n  private final SetMultimap<Step, ElementFactory> elementsDeferredBySteps =\n      LinkedHashMultimap.create();\n\n  private Elements elementUtils;\n  private Messager messager;\n  private ImmutableList<? extends Step> steps;\n\n  @Override\n  public final synchronized void init(ProcessingEnvironment processingEnv) {\n    super.init(processingEnv);\n    this.elementUtils = processingEnv.getElementUtils();\n    this.messager = processingEnv.getMessager();\n    this.steps = ImmutableList.copyOf(steps());\n  }\n\n  /**\n   * Creates {@linkplain ProcessingStep processing steps} for this processor. {@link #processingEnv}\n   * is guaranteed to be set when this method is invoked.\n   *\n   * @deprecated Implement {@link #steps()} instead.\n   */\n  @Deprecated\n  protected Iterable<? extends ProcessingStep> initSteps() {\n    throw new AssertionError(\"If steps() is not implemented, initSteps() must be.\");\n  }\n\n  /**\n   * Creates {@linkplain Step processing steps} for this processor. {@link #processingEnv} is\n   * guaranteed to be set when this method is invoked.\n   *\n   * <p>Note: If you are migrating some steps from {@link ProcessingStep} to {@link Step}, then you\n   * can call {@link #asStep(ProcessingStep)} on any unmigrated steps.\n   */\n  protected Iterable<? extends Step> steps() {\n    return Iterables.transform(initSteps(), BasicAnnotationProcessor::asStep);\n  }\n\n  /**\n   * An optional hook for logic to be executed at the end of each round.\n   *\n   * @deprecated use {@link #postRound(RoundEnvironment)} instead\n   */\n  @Deprecated\n  protected void postProcess() {}\n\n  /** An optional hook for logic to be executed at the end of each round. */\n  protected void postRound(RoundEnvironment roundEnv) {\n    if (!roundEnv.processingOver()) {\n      postProcess();\n    }\n  }\n\n  private ImmutableSet<TypeElement> getSupportedAnnotationTypeElements() {\n    checkState(steps != null);\n    return steps.stream()\n        .flatMap(step -> getSupportedAnnotationTypeElements(step).stream())\n        .collect(toImmutableSet());\n  }\n\n  private ImmutableSet<TypeElement> getSupportedAnnotationTypeElements(Step step) {\n    return step.annotations().stream()\n        .map(elementUtils::getTypeElement)\n        .filter(Objects::nonNull)\n        .collect(toImmutableSet());\n  }\n\n  /**\n   * Returns the set of supported annotation types as collected from registered {@linkplain Step\n   * processing steps}.\n   */\n  @Override\n  public final ImmutableSet<String> getSupportedAnnotationTypes() {\n    checkState(steps != null);\n    return steps.stream().flatMap(step -> step.annotations().stream()).collect(toImmutableSet());\n  }\n\n  @Override\n  public final boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n    checkState(elementUtils != null);\n    checkState(messager != null);\n    checkState(steps != null);\n\n    // If this is the last round, report all of the missing elements if there\n    // were no errors raised in the round; otherwise reporting the missing\n    // elements just adds noise to the output.\n    if (roundEnv.processingOver()) {\n      postRound(roundEnv);\n      if (!roundEnv.errorRaised()) {\n        reportMissingElements(\n            ImmutableSet.<ElementFactory>builder()\n                .addAll(deferredEnclosingElements)\n                .addAll(elementsDeferredBySteps.values())\n                .build());\n      }\n      return false;\n    }\n\n    process(getWellFormedElementsByAnnotationType(roundEnv));\n\n    postRound(roundEnv);\n\n    return false;\n  }\n\n  /** Processes the valid elements, including those previously deferred by each step. */\n  private void process(ImmutableSetMultimap<TypeElement, Element> wellFormedElements) {\n    for (Step step : steps) {\n      ImmutableSet<TypeElement> annotationTypes = getSupportedAnnotationTypeElements(step);\n      ImmutableSetMultimap<TypeElement, Element> stepElements =\n          new ImmutableSetMultimap.Builder<TypeElement, Element>()\n              .putAll(indexByAnnotation(elementsDeferredBySteps.get(step), annotationTypes))\n              .putAll(filterKeys(wellFormedElements, annotationTypes::contains))\n              .build();\n      if (stepElements.isEmpty()) {\n        elementsDeferredBySteps.removeAll(step);\n      } else {\n        Set<? extends Element> rejectedElements =\n            step.process(toClassNameKeyedMultimap(stepElements));\n        elementsDeferredBySteps.replaceValues(\n            step,\n            rejectedElements.stream()\n                .map(element -> ElementFactory.forAnnotatedElement(element, messager))\n                .collect(toImmutableList()));\n      }\n    }\n  }\n\n  private void reportMissingElements(Set<ElementFactory> missingElementFactories) {\n    for (ElementFactory missingElementFactory : missingElementFactories) {\n      Element missingElement = missingElementFactory.getElement(elementUtils);\n      if (missingElement != null) {\n        messager.printMessage(\n            ERROR,\n            processingErrorMessage(\"this \" + Ascii.toLowerCase(missingElement.getKind().name())),\n            missingElement);\n      } else {\n        messager.printMessage(ERROR, processingErrorMessage(missingElementFactory.toString));\n      }\n    }\n  }\n\n  private String processingErrorMessage(String target) {\n    return String.format(\n        \"[%s:MiscError] %s was unable to process %s because not all of its dependencies could be \"\n            + \"resolved. Check for compilation errors or a circular dependency with generated \"\n            + \"code.\",\n        getClass().getSimpleName(), getClass().getCanonicalName(), target);\n  }\n\n  /**\n   * Returns the superficially validated annotated elements of this round, including the validated\n   * previously ill-formed elements. Also update {@link #deferredEnclosingElements}.\n   *\n   * <p>Note that the elements deferred by processing steps are guaranteed to be well-formed;\n   * therefore, they are ignored (not returned) here, and they will be considered directly in the\n   * {@link #process(ImmutableSetMultimap)} method.\n   */\n  private ImmutableSetMultimap<TypeElement, Element> getWellFormedElementsByAnnotationType(\n      RoundEnvironment roundEnv) {\n    ImmutableSet<ElementFactory> deferredEnclosingElementsCopy =\n        ImmutableSet.copyOf(deferredEnclosingElements);\n    deferredEnclosingElements.clear();\n\n    ImmutableSetMultimap.Builder<TypeElement, Element> prevIllFormedElementsBuilder =\n        ImmutableSetMultimap.builder();\n    for (ElementFactory deferredElementFactory : deferredEnclosingElementsCopy) {\n      Element deferredElement = deferredElementFactory.getElement(elementUtils);\n      if (deferredElement != null) {\n        findAnnotatedElements(\n            deferredElement, getSupportedAnnotationTypeElements(), prevIllFormedElementsBuilder);\n      } else {\n        deferredEnclosingElements.add(deferredElementFactory);\n      }\n    }\n\n    ImmutableSetMultimap<TypeElement, Element> prevIllFormedElements =\n        prevIllFormedElementsBuilder.build();\n\n    ImmutableSetMultimap.Builder<TypeElement, Element> wellFormedElementsBuilder =\n        ImmutableSetMultimap.builder();\n\n    // For optimization purposes, the ElementFactory instances for packages and types that have\n    // already been verified to be well-formed are stored.\n    Set<ElementFactory> wellFormedPackageOrTypeElements = new LinkedHashSet<>();\n\n    /* Look at\n     *   1. the previously ill-formed elements which have a present enclosing type (in case of\n     *      Package element, the package itself), and\n     *   2. the new elements from this round\n     * and validate them.\n     */\n    for (TypeElement annotationType : getSupportedAnnotationTypeElements()) {\n      Set<? extends Element> roundElements = roundEnv.getElementsAnnotatedWith(annotationType);\n\n      for (Element element : Sets.union(roundElements, prevIllFormedElements.get(annotationType))) {\n        // For every element that is not module/package, to be well-formed its\n        // enclosing-type in its entirety should be well-formed. Since modules\n        // don't get annotated (and not supported here) they can be ignored.\n        Element enclosing = (element.getKind() == PACKAGE) ? element : getEnclosingType(element);\n        ElementFactory enclosingFactory = ElementFactory.forAnnotatedElement(enclosing, messager);\n\n        boolean isWellFormedElement =\n            wellFormedPackageOrTypeElements.contains(enclosingFactory)\n                || (!deferredEnclosingElements.contains(enclosingFactory)\n                    && validateElement(enclosing));\n        if (isWellFormedElement) {\n          wellFormedElementsBuilder.put(annotationType, element);\n          wellFormedPackageOrTypeElements.add(enclosingFactory);\n        } else {\n          deferredEnclosingElements.add(enclosingFactory);\n        }\n      }\n    }\n\n    return wellFormedElementsBuilder.build();\n  }\n\n  private ImmutableSetMultimap<TypeElement, Element> indexByAnnotation(\n      Set<ElementFactory> annotatedElementFactories, ImmutableSet<TypeElement> annotationTypes) {\n    ImmutableSetMultimap.Builder<TypeElement, Element> deferredElementsByAnnotationTypeBuilder =\n        ImmutableSetMultimap.builder();\n    for (ElementFactory elementFactory : annotatedElementFactories) {\n      Element element = elementFactory.getElement(elementUtils);\n      if (element != null) {\n        for (TypeElement annotationType : annotationTypes) {\n          if (isAnnotationPresent(element, annotationType)) {\n            deferredElementsByAnnotationTypeBuilder.put(annotationType, element);\n          }\n        }\n      }\n    }\n    return deferredElementsByAnnotationTypeBuilder.build();\n  }\n\n  /**\n   * Adds {@code element} and its enclosed elements to {@code annotatedElements} if they are\n   * annotated with any annotations in {@code annotationTypes}. Does not traverse to member types of\n   * {@code element}, so that if {@code Outer} is passed in the example below, looking for\n   * {@code @X}, then {@code Outer}, {@code Outer.foo}, and {@code Outer.foo()} will be added to the\n   * multimap, but neither {@code Inner} nor its members will.\n   *\n   * <pre>{@code\n   * @X class Outer {\n   *   @X Object foo;\n   *   @X void foo() {}\n   *   @X static class Inner {\n   *     @X Object bar;\n   *     @X void bar() {}\n   *   }\n   * }\n   * }</pre>\n   */\n  private static void findAnnotatedElements(\n      Element element,\n      ImmutableSet<TypeElement> annotationTypes,\n      ImmutableSetMultimap.Builder<TypeElement, Element> annotatedElements) {\n    for (Element enclosedElement : element.getEnclosedElements()) {\n      if (!enclosedElement.getKind().isClass() && !enclosedElement.getKind().isInterface()) {\n        findAnnotatedElements(enclosedElement, annotationTypes, annotatedElements);\n      }\n    }\n\n    // element.getEnclosedElements() does NOT return parameter or type parameter elements\n\n    Parameterizable parameterizable = null;\n    if (isType(element)) {\n      parameterizable = asType(element);\n    } else if (isExecutable(element)) {\n      ExecutableElement executableElement = asExecutable(element);\n      parameterizable = executableElement;\n      for (VariableElement parameterElement : executableElement.getParameters()) {\n        findAnnotatedElements(parameterElement, annotationTypes, annotatedElements);\n      }\n    }\n    if (parameterizable != null) {\n      for (TypeParameterElement parameterElement : parameterizable.getTypeParameters()) {\n        findAnnotatedElements(parameterElement, annotationTypes, annotatedElements);\n      }\n    }\n\n    for (TypeElement annotationType : annotationTypes) {\n      if (isAnnotationPresent(element, annotationType)) {\n        annotatedElements.put(annotationType, element);\n      }\n    }\n  }\n\n  /**\n   * Returns the nearest enclosing {@link TypeElement} to the current element, throwing an {@link\n   * IllegalArgumentException} if the provided {@link Element} is not enclosed by a type.\n   */\n  // TODO(user) move to MoreElements and make public.\n  private static TypeElement getEnclosingType(Element element) {\n    Element enclosingTypeElement = element;\n    while (enclosingTypeElement != null && !isType(enclosingTypeElement)) {\n      enclosingTypeElement = enclosingTypeElement.getEnclosingElement();\n    }\n\n    if (enclosingTypeElement == null) {\n      throw new IllegalArgumentException(element + \" is not enclosed in any TypeElement.\");\n    }\n    return asType(enclosingTypeElement);\n  }\n\n  private static ImmutableSetMultimap<String, Element> toClassNameKeyedMultimap(\n      SetMultimap<TypeElement, Element> elements) {\n    ImmutableSetMultimap.Builder<String, Element> builder = ImmutableSetMultimap.builder();\n    elements\n        .asMap()\n        .forEach(\n            (annotation, element) ->\n                builder.putAll(annotation.getQualifiedName().toString(), element));\n    return builder.build();\n  }\n\n  private static boolean isExecutable(Element element) {\n    return element.getKind() == METHOD || element.getKind() == CONSTRUCTOR;\n  }\n\n  /**\n   * Wraps the passed {@link ProcessingStep} in a {@link Step}. This is a convenience method to\n   * allow incremental migration to a String-based API. This method can be used to return a not yet\n   * converted {@link ProcessingStep} from {@link BasicAnnotationProcessor#steps()}.\n   */\n  protected static Step asStep(ProcessingStep processingStep) {\n    return new ProcessingStepAsStep(processingStep);\n  }\n\n  /**\n   * The unit of processing logic that runs under the guarantee that all elements are complete and\n   * well-formed. A step may reject elements that are not ready for processing but may be at a later\n   * round.\n   */\n  public interface Step {\n\n    /**\n     * The set of fully-qualified annotation type names processed by this step.\n     *\n     * <p>Warning: If the returned names are not names of annotations, they'll be ignored.\n     */\n    Set<String> annotations();\n\n    /**\n     * The implementation of processing logic for the step. It is guaranteed that the keys in {@code\n     * elementsByAnnotation} will be a subset of the set returned by {@link #annotations()}.\n     *\n     * @return the elements (a subset of the values of {@code elementsByAnnotation}) that this step\n     *     is unable to process, possibly until a later processing round. These elements will be\n     *     passed back to this step at the next round of processing.\n     */\n    Set<? extends Element> process(ImmutableSetMultimap<String, Element> elementsByAnnotation);\n  }\n\n  /**\n   * The unit of processing logic that runs under the guarantee that all elements are complete and\n   * well-formed. A step may reject elements that are not ready for processing but may be at a later\n   * round.\n   *\n   * @deprecated Implement {@link Step} instead. See {@link BasicAnnotationProcessor#steps()}.\n   */\n  @Deprecated\n  public interface ProcessingStep {\n\n    /** The set of annotation types processed by this step. */\n    Set<? extends Class<? extends Annotation>> annotations();\n\n    /**\n     * The implementation of processing logic for the step. It is guaranteed that the keys in {@code\n     * elementsByAnnotation} will be a subset of the set returned by {@link #annotations()}.\n     *\n     * @return the elements (a subset of the values of {@code elementsByAnnotation}) that this step\n     *     is unable to process, possibly until a later processing round. These elements will be\n     *     passed back to this step at the next round of processing.\n     */\n    Set<? extends Element> process(\n        SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation);\n  }\n\n  private static class ProcessingStepAsStep implements Step {\n\n    private final ProcessingStep processingStep;\n    private final ImmutableMap<String, Class<? extends Annotation>> annotationsByName;\n\n    ProcessingStepAsStep(ProcessingStep processingStep) {\n      this.processingStep = processingStep;\n      this.annotationsByName =\n          processingStep.annotations().stream()\n              .collect(\n                  toImmutableMap(\n                      c -> requireNonNull(c.getCanonicalName()),\n                      (Class<? extends Annotation> aClass) -> aClass));\n    }\n\n    @Override\n    public Set<String> annotations() {\n      return annotationsByName.keySet();\n    }\n\n    @Override\n    public Set<? extends Element> process(\n        ImmutableSetMultimap<String, Element> elementsByAnnotation) {\n      return processingStep.process(toClassKeyedMultimap(elementsByAnnotation));\n    }\n\n    private ImmutableSetMultimap<Class<? extends Annotation>, Element> toClassKeyedMultimap(\n        SetMultimap<String, Element> elements) {\n      ImmutableSetMultimap.Builder<Class<? extends Annotation>, Element> builder =\n          ImmutableSetMultimap.builder();\n      elements\n          .asMap()\n          .forEach(\n              (annotationName, annotatedElements) -> {\n                Class<? extends Annotation> annotation = annotationsByName.get(annotationName);\n                if (annotation != null) { // should not be null\n                  builder.putAll(annotation, annotatedElements);\n                }\n              });\n      return builder.build();\n    }\n  }\n\n  /* Element Factories */\n\n  /**\n   * A factory for looking up the \"same\" annotated element in a new round.\n   *\n   * <p>When deferring work across rounds, {@link BasicAnnotationProcessor} saves an {@link\n   * ElementFactory} instead of an {@link Element}. It does this because an {@link Element} from one\n   * round is not necessarily valid in future rounds.\n   */\n  private abstract static class ElementFactory {\n    final String toString;\n\n    private ElementFactory(Element element) {\n      this.toString = element.toString();\n    }\n\n    /** An {@link ElementFactory} for an annotated element. */\n    static ElementFactory forAnnotatedElement(Element element, Messager messager) {\n      /* The name of the ElementKind constants is used instead to accommodate for RECORD\n       * and RECORD_COMPONENT kinds, which are introduced in Java 16.\n       */\n      switch (element.getKind().name()) {\n        case \"PACKAGE\":\n          return new PackageElementFactory(element);\n        case \"CLASS\":\n        case \"ENUM\":\n        case \"INTERFACE\":\n        case \"ANNOTATION_TYPE\":\n        case \"RECORD\":\n          return new TypeElementFactory(element);\n        case \"TYPE_PARAMETER\":\n          return new TypeParameterElementFactory(element, messager);\n        case \"FIELD\":\n        case \"ENUM_CONSTANT\":\n        case \"RECORD_COMPONENT\":\n          return new FieldOrRecordComponentElementFactory(element);\n        case \"CONSTRUCTOR\":\n        case \"METHOD\":\n          return new ExecutableElementFactory(element);\n        case \"PARAMETER\":\n          return new ParameterElementFactory(element);\n        default:\n          messager.printMessage(\n              WARNING,\n              String.format(\n                  \"%s does not support element type %s.\",\n                  ElementFactory.class.getCanonicalName(), element.getKind()));\n          return new UnsupportedElementFactory(element);\n      }\n    }\n\n    @Override\n    public boolean equals(@Nullable Object object) {\n      if (this == object) {\n        return true;\n      } else if (!(object instanceof ElementFactory)) {\n        return false;\n      }\n\n      ElementFactory that = (ElementFactory) object;\n      return this.toString.equals(that.toString);\n    }\n\n    @Override\n    public int hashCode() {\n      return toString.hashCode();\n    }\n\n    /**\n     * Returns the {@link Element} corresponding to the name information saved in this factory, or\n     * null if none exists.\n     */\n    abstract @Nullable Element getElement(Elements elementUtils);\n  }\n\n  /**\n   * Saves the Element reference and returns it when inquired, with the hope that the same object\n   * still represents that element, or the required information is present.\n   */\n  private static final class UnsupportedElementFactory extends ElementFactory {\n    private final Element element;\n\n    private UnsupportedElementFactory(Element element) {\n      super(element);\n      this.element = element;\n    }\n\n    @Override\n    Element getElement(Elements elementUtils) {\n      return element;\n    }\n  }\n\n  /* It's unfortunate that we have to track types and packages separately, but since there are\n   * two different methods to look them up in `Elements`, we end up with a lot of parallel\n   * logic. :(\n   */\n  private static final class PackageElementFactory extends ElementFactory {\n    private PackageElementFactory(Element element) {\n      super(element);\n    }\n\n    @Override\n    @Nullable PackageElement getElement(Elements elementUtils) {\n      return elementUtils.getPackageElement(toString);\n    }\n  }\n\n  private static final class TypeElementFactory extends ElementFactory {\n    private TypeElementFactory(Element element) {\n      super(element);\n    }\n\n    @Override\n    @Nullable TypeElement getElement(Elements elementUtils) {\n      return elementUtils.getTypeElement(toString);\n    }\n  }\n\n  private static final class TypeParameterElementFactory extends ElementFactory {\n    private final ElementFactory enclosingElementFactory;\n\n    private TypeParameterElementFactory(Element element, Messager messager) {\n      super(element);\n      this.enclosingElementFactory =\n          ElementFactory.forAnnotatedElement(element.getEnclosingElement(), messager);\n    }\n\n    @Override\n    @Nullable TypeParameterElement getElement(Elements elementUtils) {\n      Parameterizable enclosingElement =\n          (Parameterizable) enclosingElementFactory.getElement(elementUtils);\n      if (enclosingElement == null) {\n        return null;\n      }\n      return enclosingElement.getTypeParameters().stream()\n          .filter(typeParamElement -> toString.equals(typeParamElement.toString()))\n          .collect(onlyElement());\n    }\n\n    @Override\n    public boolean equals(@Nullable Object object) {\n      if (this == object) {\n        return true;\n      } else if (!(object instanceof TypeParameterElementFactory)) {\n        return false;\n      }\n\n      TypeParameterElementFactory that = (TypeParameterElementFactory) object;\n      return this.toString.equals(that.toString)\n          && this.enclosingElementFactory.equals(that.enclosingElementFactory);\n    }\n\n    @Override\n    public int hashCode() {\n      return Objects.hash(toString, enclosingElementFactory);\n    }\n  }\n\n  /** Represents FIELD, ENUM_CONSTANT, and RECORD_COMPONENT */\n  private static class FieldOrRecordComponentElementFactory extends ElementFactory {\n    private final TypeElementFactory enclosingTypeElementFactory;\n    private final ElementKind elementKind;\n\n    private FieldOrRecordComponentElementFactory(Element element) {\n      super(element); // toString is its simple name.\n      this.enclosingTypeElementFactory = new TypeElementFactory(getEnclosingType(element));\n      this.elementKind = element.getKind();\n    }\n\n    @Override\n    @Nullable Element getElement(Elements elementUtils) {\n      TypeElement enclosingTypeElement = enclosingTypeElementFactory.getElement(elementUtils);\n      if (enclosingTypeElement == null) {\n        return null;\n      }\n      return enclosingTypeElement.getEnclosedElements().stream()\n          .filter(\n              element ->\n                  elementKind.equals(element.getKind()) && toString.equals(element.toString()))\n          .collect(onlyElement());\n    }\n\n    @Override\n    public boolean equals(@Nullable Object object) {\n      if (!super.equals(object) || !(object instanceof FieldOrRecordComponentElementFactory)) {\n        return false;\n      }\n      // To distinguish between a field and record_component\n      FieldOrRecordComponentElementFactory that = (FieldOrRecordComponentElementFactory) object;\n      return this.elementKind == that.elementKind;\n    }\n\n    @Override\n    public int hashCode() {\n      return Objects.hash(toString, elementKind);\n    }\n  }\n\n  /**\n   * Represents METHOD and CONSTRUCTOR.\n   *\n   * <p>The {@code equals()} and {@code hashCode()} have been overridden since the {@code toString}\n   * alone is not sufficient to make a distinction in all overloaded cases. For example, {@code <C\n   * extends Set<String>> void m(C c) {}}, and {@code <C extends SortedSet<String>> void m(C c) {}}\n   * both have the same toString {@code <C>m(C)} but are valid cases for overloading methods.\n   * Moreover, the needed enclosing type-element information is not included in the toString.\n   *\n   * <p>The executable element is retrieved by saving its enclosing type element, simple name, and\n   * ordinal position in the source code relative to other related overloaded methods, meaning those\n   * with the same simple name. This is possible because according to Java language specification\n   * for {@link TypeElement#getEnclosedElements()}: \"As a particular instance of the general\n   * accuracy requirements and the ordering behavior required of this interface, the list of\n   * enclosed elements will be returned to the natural order for the originating source of\n   * information about the type. For example, if the information about the type is originating from\n   * a source file, the elements will be returned in source code order. (However, in that case the\n   * ordering of implicitly declared elements, such as default constructors, is not specified.)\"\n   *\n   * <p>Simple name is saved since comparing the toString is not reliable when at least one\n   * parameter references ERROR, possibly because it is not generated yet. For example, method\n   * {@code void m(SomeGeneratedClass sgc)}, before the generation of {@code SomeGeneratedClass} has\n   * the toString {@code m(SomeGeneratedClass)}; however, after the generation it will have toString\n   * equal to {@code m(test.SomeGeneratedClass)} assuming that the package name is \"test\".\n   */\n  private static final class ExecutableElementFactory extends ElementFactory {\n    private final TypeElementFactory enclosingTypeElementFactory;\n    private final Name simpleName;\n\n    /**\n     * The index of the element among all elements of the same kind within the enclosing type. If\n     * this is method {@code foo(...)} and the index is 0, that means that the method is the first\n     * method called {@code foo} in the enclosing type.\n     */\n    private final int sameNameIndex;\n\n    private ExecutableElementFactory(Element element) {\n      super(element);\n      TypeElement enclosingTypeElement = getEnclosingType(element);\n      this.enclosingTypeElementFactory = new TypeElementFactory(enclosingTypeElement);\n      this.simpleName = element.getSimpleName();\n\n      ImmutableList<Element> methods = sameNameMethods(enclosingTypeElement, simpleName);\n      this.sameNameIndex = methods.indexOf(element);\n      checkState(this.sameNameIndex >= 0, \"Did not find %s in %s\", element, methods);\n    }\n\n    @Override\n    @Nullable ExecutableElement getElement(Elements elementUtils) {\n      TypeElement enclosingTypeElement = enclosingTypeElementFactory.getElement(elementUtils);\n      if (enclosingTypeElement == null) {\n        return null;\n      }\n      ImmutableList<Element> methods = sameNameMethods(enclosingTypeElement, simpleName);\n      return asExecutable(methods.get(sameNameIndex));\n    }\n\n    private static ImmutableList<Element> sameNameMethods(\n        TypeElement enclosingTypeElement, Name simpleName) {\n      return enclosingTypeElement.getEnclosedElements().stream()\n          .filter(element -> element.getSimpleName().equals(simpleName) && isExecutable(element))\n          .collect(toImmutableList());\n    }\n\n    @Override\n    public boolean equals(@Nullable Object object) {\n      if (this == object) {\n        return true;\n      } else if (!(object instanceof ExecutableElementFactory)) {\n        return false;\n      }\n\n      ExecutableElementFactory that = (ExecutableElementFactory) object;\n      return this.simpleName.equals(that.simpleName)\n          && this.sameNameIndex == that.sameNameIndex\n          && this.enclosingTypeElementFactory.equals(that.enclosingTypeElementFactory);\n    }\n\n    @Override\n    public int hashCode() {\n      return Objects.hash(simpleName, sameNameIndex, enclosingTypeElementFactory);\n    }\n  }\n\n  private static final class ParameterElementFactory extends ElementFactory {\n    private final ExecutableElementFactory enclosingExecutableElementFactory;\n\n    private ParameterElementFactory(Element element) {\n      super(element);\n      this.enclosingExecutableElementFactory =\n          new ExecutableElementFactory(element.getEnclosingElement());\n    }\n\n    @Override\n    @Nullable VariableElement getElement(Elements elementUtils) {\n      ExecutableElement enclosingExecutableElement =\n          enclosingExecutableElementFactory.getElement(elementUtils);\n      if (enclosingExecutableElement == null) {\n        return null;\n      } else {\n        return enclosingExecutableElement.getParameters().stream()\n            .filter(paramElement -> toString.equals(paramElement.toString()))\n            .collect(onlyElement());\n      }\n    }\n\n    @Override\n    public boolean equals(@Nullable Object object) {\n      if (this == object) {\n        return true;\n      } else if (!(object instanceof ParameterElementFactory)) {\n        return false;\n      }\n\n      ParameterElementFactory that = (ParameterElementFactory) object;\n      return this.toString.equals(that.toString)\n          && this.enclosingExecutableElementFactory.equals(that.enclosingExecutableElementFactory);\n    }\n\n    @Override\n    public int hashCode() {\n      return Objects.hash(toString, enclosingExecutableElementFactory);\n    }\n  }\n}\n"
  },
  {
    "path": "common/src/main/java/com/google/auto/common/GeneratedAnnotationSpecs.java",
    "content": "/*\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport com.squareup.javapoet.AnnotationSpec;\nimport com.squareup.javapoet.ClassName;\nimport java.util.Optional;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.util.Elements;\n\n/** Utility methods for writing {@code @Generated} annotations using JavaPoet. */\npublic final class GeneratedAnnotationSpecs {\n\n  private GeneratedAnnotationSpecs() {}\n\n  /**\n   * Returns {@code @Generated(\"processorClass\")} if either {@code\n   * javax.annotation.processing.Generated} or {@code javax.annotation.Generated} is {@linkplain\n   * GeneratedAnnotations#generatedAnnotation(Elements) available at compile time}.\n   *\n   * @deprecated prefer {@link #generatedAnnotationSpec(Elements, SourceVersion, Class)}\n   */\n  @Deprecated\n  public static Optional<AnnotationSpec> generatedAnnotationSpec(\n      Elements elements, Class<?> processorClass) {\n    return generatedAnnotationSpecBuilder(elements, processorClass)\n        .map(AnnotationSpec.Builder::build);\n  }\n\n  /**\n   * Returns {@code @Generated(value = \"processorClass\", comments = \"comments\")} if either {@code\n   * javax.annotation.processing.Generated} or {@code javax.annotation.Generated} is {@linkplain\n   * GeneratedAnnotations#generatedAnnotation(Elements) available at compile time}.\n   *\n   * @deprecated prefer {@link #generatedAnnotationSpec(Elements, SourceVersion, Class, String)}\n   */\n  @Deprecated\n  public static Optional<AnnotationSpec> generatedAnnotationSpec(\n      Elements elements, Class<?> processorClass, String comments) {\n    return generatedAnnotationSpecBuilder(elements, processorClass)\n        .map(annotation -> annotation.addMember(\"comments\", \"$S\", comments).build());\n  }\n\n  /**\n   * Returns {@code @Generated(\"processorClass\")} for the target {@code SourceVersion}.\n   *\n   * <p>Returns {@code javax.annotation.processing.Generated} for JDK 9 and newer, {@code\n   * javax.annotation.Generated} for earlier releases, and Optional#empty()} if the annotation is\n   * not available.\n   */\n  public static Optional<AnnotationSpec> generatedAnnotationSpec(\n      Elements elements, SourceVersion sourceVersion, Class<?> processorClass) {\n    return generatedAnnotationSpecBuilder(elements, sourceVersion, processorClass)\n        .map(AnnotationSpec.Builder::build);\n  }\n\n  /**\n   * Returns {@code @Generated(value = \"processorClass\", comments = \"comments\")} for the target\n   * {@code SourceVersion}.\n   *\n   * <p>Returns {@code javax.annotation.processing.Generated} for JDK 9 and newer, {@code\n   * javax.annotation.Generated} for earlier releases, and Optional#empty()} if the annotation is\n   * not available.\n   */\n  public static Optional<AnnotationSpec> generatedAnnotationSpec(\n      Elements elements, SourceVersion sourceVersion, Class<?> processorClass, String comments) {\n    return generatedAnnotationSpecBuilder(elements, sourceVersion, processorClass)\n        .map(annotation -> annotation.addMember(\"comments\", \"$S\", comments).build());\n  }\n\n  private static Optional<AnnotationSpec.Builder> generatedAnnotationSpecBuilder(\n      Elements elements, Class<?> processorClass) {\n    return GeneratedAnnotations.generatedAnnotation(elements)\n        .map(\n            generated ->\n                AnnotationSpec.builder(ClassName.get(generated))\n                    .addMember(\"value\", \"$S\", processorClass.getCanonicalName()));\n  }\n\n  private static Optional<AnnotationSpec.Builder> generatedAnnotationSpecBuilder(\n      Elements elements, SourceVersion sourceVersion, Class<?> processorClass) {\n    return GeneratedAnnotations.generatedAnnotation(elements, sourceVersion)\n        .map(\n            generated ->\n                AnnotationSpec.builder(ClassName.get(generated))\n                    .addMember(\"value\", \"$S\", processorClass.getCanonicalName()));\n  }\n}\n"
  },
  {
    "path": "common/src/main/java/com/google/auto/common/GeneratedAnnotations.java",
    "content": "/*\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport java.util.Optional;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.util.Elements;\n\n/** Utility methods for writing {@code @Generated} annotations. */\npublic final class GeneratedAnnotations {\n  private GeneratedAnnotations() {}\n\n  /**\n   * Returns the element corresponding to the version of the {@code @Generated} annotation present\n   * in the compile-time class- or module-path.\n   *\n   * <p>First looks for {@code javax.annotation.processing.Generated}, and then {@code\n   * javax.annotation.Generated}. Returns whichever is in the classpath (or modulepath), or {@link\n   * Optional#empty()} if neither is.\n   *\n   * @deprecated prefer {@link #generatedAnnotation(Elements, SourceVersion)}\n   */\n  @Deprecated\n  public static Optional<TypeElement> generatedAnnotation(Elements elements) {\n    TypeElement jdk9Generated = elements.getTypeElement(\"javax.annotation.processing.Generated\");\n    if (jdk9Generated != null) {\n      return Optional.of(jdk9Generated);\n    }\n    return Optional.ofNullable(elements.getTypeElement(\"javax.annotation.Generated\"));\n  }\n\n  /**\n   * Returns the element corresponding to the {@code @Generated} annotation present at the target\n   * {@code SourceVersion}.\n   *\n   * <p>Returns {@code javax.annotation.processing.Generated} for JDK 9 and newer, {@code\n   * javax.annotation.Generated} for earlier releases, and Optional#empty()} if the annotation is\n   * not available.\n   */\n  public static Optional<TypeElement> generatedAnnotation(\n      Elements elements, SourceVersion sourceVersion) {\n    return Optional.ofNullable(\n        elements.getTypeElement(\n            sourceVersion.compareTo(SourceVersion.RELEASE_8) > 0\n                ? \"javax.annotation.processing.Generated\"\n                : \"javax.annotation.Generated\"));\n  }\n}\n"
  },
  {
    "path": "common/src/main/java/com/google/auto/common/MoreElements.java",
    "content": "/*\n * Copyright 2013 Google LLC\n * Copyright (C) 2013 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport static com.google.common.collect.ImmutableSet.toImmutableSet;\nimport static javax.lang.model.element.ElementKind.PACKAGE;\nimport static javax.lang.model.element.Modifier.STATIC;\n\nimport com.google.auto.common.Overrides.ExplicitOverrides;\nimport com.google.common.annotations.Beta;\nimport com.google.common.base.Optional;\nimport com.google.common.base.Predicate;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.LinkedHashMultimap;\nimport com.google.common.collect.SetMultimap;\nimport java.lang.annotation.Annotation;\nimport java.util.Collection;\nimport java.util.LinkedHashSet;\nimport java.util.List;\nimport java.util.Set;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.Modifier;\nimport javax.lang.model.element.PackageElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.TypeParameterElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.ElementFilter;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.SimpleElementVisitor8;\nimport javax.lang.model.util.Types;\n\n/**\n * Static utility methods pertaining to {@link Element} instances.\n *\n * @author Gregory Kick\n */\n@Beta\npublic final class MoreElements {\n  /**\n   * An alternate implementation of {@link Elements#getPackageOf} that does not require an {@link\n   * Elements} instance.\n   *\n   * @throws NullPointerException if {@code element} is {@code null}\n   */\n  public static PackageElement getPackage(Element element) {\n    while (element.getKind() != PACKAGE) {\n      element = element.getEnclosingElement();\n    }\n    return (PackageElement) element;\n  }\n\n  private static final class PackageElementVisitor extends CastingElementVisitor<PackageElement> {\n    private static final PackageElementVisitor INSTANCE = new PackageElementVisitor();\n\n    PackageElementVisitor() {\n      super(\"package element\");\n    }\n\n    @Override\n    public PackageElement visitPackage(PackageElement e, Void ignore) {\n      return e;\n    }\n  }\n\n  /**\n   * Returns the given {@link Element} instance as {@link PackageElement}.\n   *\n   * <p>This method is functionally equivalent to an {@code instanceof} check and a cast, but should\n   * always be used over that idiom as instructed in the documentation for {@link Element}.\n   *\n   * @throws NullPointerException if {@code element} is {@code null}\n   * @throws IllegalArgumentException if {@code element} isn't a {@link PackageElement}.\n   */\n  public static PackageElement asPackage(Element element) {\n    return element.accept(PackageElementVisitor.INSTANCE, null);\n  }\n\n  private static final class TypeElementVisitor extends CastingElementVisitor<TypeElement> {\n    private static final TypeElementVisitor INSTANCE = new TypeElementVisitor();\n\n    TypeElementVisitor() {\n      super(\"type element\");\n    }\n\n    @Override\n    public TypeElement visitType(TypeElement e, Void ignore) {\n      return e;\n    }\n  }\n\n  /**\n   * Returns true if the given {@link Element} instance is a {@link TypeElement}.\n   *\n   * <p>This method is functionally equivalent to an {@code instanceof} check, but should always be\n   * used over that idiom as instructed in the documentation for {@link Element}.\n   *\n   * @throws NullPointerException if {@code element} is {@code null}\n   */\n  public static boolean isType(Element element) {\n    return element.getKind().isClass() || element.getKind().isInterface();\n  }\n\n  /**\n   * Returns the given {@link Element} instance as {@link TypeElement}.\n   *\n   * <p>This method is functionally equivalent to an {@code instanceof} check and a cast, but should\n   * always be used over that idiom as instructed in the documentation for {@link Element}.\n   *\n   * @throws NullPointerException if {@code element} is {@code null}\n   * @throws IllegalArgumentException if {@code element} isn't a {@link TypeElement}.\n   */\n  public static TypeElement asType(Element element) {\n    return element.accept(TypeElementVisitor.INSTANCE, null);\n  }\n\n  /**\n   * Returns the given {@link Element} instance as {@link TypeParameterElement}.\n   *\n   * <p>This method is functionally equivalent to an {@code instanceof} check and a cast, but should\n   * always be used over that idiom as instructed in the documentation for {@link Element}.\n   *\n   * @throws NullPointerException if {@code element} is {@code null}\n   * @throws IllegalArgumentException if {@code element} isn't a {@link TypeParameterElement}.\n   */\n  public static TypeParameterElement asTypeParameter(Element element) {\n    return element.accept(TypeParameterElementVisitor.INSTANCE, null);\n  }\n\n  private static final class TypeParameterElementVisitor\n      extends CastingElementVisitor<TypeParameterElement> {\n    private static final TypeParameterElementVisitor INSTANCE = new TypeParameterElementVisitor();\n\n    TypeParameterElementVisitor() {\n      super(\"type parameter element\");\n    }\n\n    @Override\n    public TypeParameterElement visitTypeParameter(TypeParameterElement e, Void ignore) {\n      return e;\n    }\n  }\n\n  private static final class VariableElementVisitor extends CastingElementVisitor<VariableElement> {\n    private static final VariableElementVisitor INSTANCE = new VariableElementVisitor();\n\n    VariableElementVisitor() {\n      super(\"variable element\");\n    }\n\n    @Override\n    public VariableElement visitVariable(VariableElement e, Void ignore) {\n      return e;\n    }\n  }\n\n  /**\n   * Returns the given {@link Element} instance as {@link VariableElement}.\n   *\n   * <p>This method is functionally equivalent to an {@code instanceof} check and a cast, but should\n   * always be used over that idiom as instructed in the documentation for {@link Element}.\n   *\n   * @throws NullPointerException if {@code element} is {@code null}\n   * @throws IllegalArgumentException if {@code element} isn't a {@link VariableElement}.\n   */\n  public static VariableElement asVariable(Element element) {\n    return element.accept(VariableElementVisitor.INSTANCE, null);\n  }\n\n  private static final class ExecutableElementVisitor\n      extends CastingElementVisitor<ExecutableElement> {\n    private static final ExecutableElementVisitor INSTANCE = new ExecutableElementVisitor();\n\n    ExecutableElementVisitor() {\n      super(\"executable element\");\n    }\n\n    @Override\n    public ExecutableElement visitExecutable(ExecutableElement e, Void label) {\n      return e;\n    }\n  }\n\n  /**\n   * Returns the given {@link Element} instance as {@link ExecutableElement}.\n   *\n   * <p>This method is functionally equivalent to an {@code instanceof} check and a cast, but should\n   * always be used over that idiom as instructed in the documentation for {@link Element}.\n   *\n   * @throws NullPointerException if {@code element} is {@code null}\n   * @throws IllegalArgumentException if {@code element} isn't a {@link ExecutableElement}.\n   */\n  public static ExecutableElement asExecutable(Element element) {\n    return element.accept(ExecutableElementVisitor.INSTANCE, null);\n  }\n\n  /**\n   * Returns {@code true} iff the given element has an {@link AnnotationMirror} whose {@linkplain\n   * AnnotationMirror#getAnnotationType() annotation type} has the same canonical name as that of\n   * {@code annotationClass}. This method is a safer alternative to calling {@link\n   * Element#getAnnotation} and checking for {@code null} as it avoids any interaction with\n   * annotation proxies.\n   */\n  public static boolean isAnnotationPresent(\n      Element element, Class<? extends Annotation> annotationClass) {\n    return getAnnotationMirror(element, annotationClass).isPresent();\n  }\n\n  /**\n   * Returns {@code true} iff the given element has an {@link AnnotationMirror} whose {@linkplain\n   * AnnotationMirror#getAnnotationType() annotation type} has the same fully qualified name as that\n   * of {@code annotation}. This method is a safer alternative to calling {@link\n   * Element#getAnnotation} and checking for {@code null} as it avoids any interaction with\n   * annotation proxies.\n   */\n  public static boolean isAnnotationPresent(Element element, TypeElement annotation) {\n    return getAnnotationMirror(element, annotation).isPresent();\n  }\n\n  /**\n   * Returns {@code true} iff the given element has an {@link AnnotationMirror} whose {@linkplain\n   * AnnotationMirror#getAnnotationType() annotation type} has {@code annotationName} as its\n   * canonical name. This method is a safer alternative to calling {@link Element#getAnnotation} and\n   * checking for {@code null} as it avoids any interaction with annotation proxies.\n   */\n  public static boolean isAnnotationPresent(Element element, String annotationName) {\n    return getAnnotationMirror(element, annotationName).isPresent();\n  }\n\n  /**\n   * Returns an {@link AnnotationMirror} for the annotation of type {@code annotationClass} on\n   * {@code element}, or {@link Optional#absent()} if no such annotation exists. This method is a\n   * safer alternative to calling {@link Element#getAnnotation} as it avoids any interaction with\n   * annotation proxies.\n   */\n  public static Optional<AnnotationMirror> getAnnotationMirror(\n      Element element, Class<? extends Annotation> annotationClass) {\n    String name = annotationClass.getCanonicalName();\n    if (name == null) {\n      return Optional.absent();\n    }\n    return getAnnotationMirror(element, name);\n  }\n\n  /**\n   * Returns an {@link AnnotationMirror} for the annotation of type {@code annotation} on {@code\n   * element}, or {@link Optional#absent()} if no such annotation exists. This method is a safer\n   * alternative to calling {@link Element#getAnnotation} as it avoids any interaction with\n   * annotation proxies.\n   */\n  public static Optional<AnnotationMirror> getAnnotationMirror(\n      Element element, TypeElement annotation) {\n    for (AnnotationMirror elementAnnotation : element.getAnnotationMirrors()) {\n      if (elementAnnotation.getAnnotationType().asElement().equals(annotation)) {\n        return Optional.of(elementAnnotation);\n      }\n    }\n    return Optional.absent();\n  }\n\n  /**\n   * Returns an {@link AnnotationMirror} for the annotation whose type's canonical name is on {@code\n   * element}, or {@link Optional#absent()} if no such annotation exists. This method is a safer\n   * alternative to calling {@link Element#getAnnotation} as it avoids any interaction with\n   * annotation proxies.\n   */\n  public static Optional<AnnotationMirror> getAnnotationMirror(\n      Element element, String annotationName) {\n    for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) {\n      TypeElement annotationTypeElement = asType(annotationMirror.getAnnotationType().asElement());\n      if (annotationTypeElement.getQualifiedName().contentEquals(annotationName)) {\n        return Optional.of(annotationMirror);\n      }\n    }\n    return Optional.absent();\n  }\n\n  /**\n   * Returns a {@link Predicate} that can be used to filter elements by {@link Modifier}. The\n   * predicate returns {@code true} if the input {@link Element} has all of the given {@code\n   * modifiers}, perhaps in addition to others.\n   *\n   * <p>Here is an example how one could get a List of static methods of a class:\n   *\n   * <pre>{@code\n   * FluentIterable.from(ElementFilter.methodsIn(clazzElement.getEnclosedElements()))\n   *     .filter(MoreElements.hasModifiers(Modifier.STATIC)).toList();\n   * }</pre>\n   */\n  public static <T extends Element> Predicate<T> hasModifiers(Modifier... modifiers) {\n    return hasModifiers(ImmutableSet.copyOf(modifiers));\n  }\n\n  /**\n   * Returns a {@link Predicate} that can be used to filter elements by {@link Modifier}. The\n   * predicate returns {@code true} if the input {@link Element} has all of the given {@code\n   * modifiers}, perhaps in addition to others.\n   *\n   * <p>Here is an example how one could get a List of methods with certain modifiers of a class:\n   *\n   * <pre>{@code\n   * Set<Modifier> modifiers = ...;\n   * FluentIterable.from(ElementFilter.methodsIn(clazzElement.getEnclosedElements()))\n   *     .filter(MoreElements.hasModifiers(modifiers)).toList();\n   * }</pre>\n   */\n  public static <T extends Element> Predicate<T> hasModifiers(final Set<Modifier> modifiers) {\n    return new Predicate<T>() {\n      @Override\n      public boolean apply(T input) {\n        return input.getModifiers().containsAll(modifiers);\n      }\n    };\n  }\n\n  /**\n   * Returns the set of all non-private, non-static methods from {@code type}, including methods\n   * that it inherits from its ancestors. Inherited methods that are overridden are not included in\n   * the result. So if {@code type} defines {@code public String toString()}, the returned set will\n   * contain that method, but not the {@code toString()} method defined by {@code Object}.\n   *\n   * <p>The returned set may contain more than one method with the same signature, if {@code type}\n   * inherits those methods from different ancestors. For example, if it inherits from unrelated\n   * interfaces {@code One} and {@code Two} which each define {@code void foo();}, and if it does\n   * not itself override the {@code foo()} method, then both {@code One.foo()} and {@code Two.foo()}\n   * will be in the returned set.\n   *\n   * <p>The order of the returned set is deterministic: within a class or interface, methods are in\n   * the order they appear in the source code; methods in ancestors come before methods in\n   * descendants; methods in interfaces come before methods in classes; and in a class or interface\n   * that has more than one superinterface, the interfaces are in the order of their appearance in\n   * {@code implements} or {@code extends}.\n   *\n   * @param type the type whose own and inherited methods are to be returned\n   * @param elementUtils an {@link Elements} object, typically returned by {@link\n   *     javax.annotation.processing.AbstractProcessor#processingEnv processingEnv}.{@link\n   *     javax.annotation.processing.ProcessingEnvironment#getElementUtils getElementUtils()}\n   * @deprecated The method {@link #getLocalAndInheritedMethods(TypeElement, Types, Elements)} has\n   *     better consistency between Java compilers.\n   */\n  @Deprecated\n  public static ImmutableSet<ExecutableElement> getLocalAndInheritedMethods(\n      TypeElement type, Elements elementUtils) {\n    Overrides overrides = new Overrides.NativeOverrides(elementUtils);\n    return getLocalAndInheritedMethods(type, overrides);\n  }\n\n  /**\n   * Returns the set of all non-private, non-static methods from {@code type}, including methods\n   * that it inherits from its ancestors. Inherited methods that are overridden are not included in\n   * the result. So if {@code type} defines {@code public String toString()}, the returned set will\n   * contain that method, but not the {@code toString()} method defined by {@code Object}.\n   *\n   * <p>The returned set may contain more than one method with the same signature, if {@code type}\n   * inherits those methods from different ancestors. For example, if it inherits from unrelated\n   * interfaces {@code One} and {@code Two} which each define {@code void foo();}, and if it does\n   * not itself override the {@code foo()} method, then both {@code One.foo()} and {@code Two.foo()}\n   * will be in the returned set.\n   *\n   * <p>The order of the returned set is deterministic: within a class or interface, methods are in\n   * the order they appear in the source code; methods in ancestors come before methods in\n   * descendants; methods in interfaces come before methods in classes; and in a class or interface\n   * that has more than one superinterface, the interfaces are in the order of their appearance in\n   * {@code implements} or {@code extends}.\n   *\n   * @param type the type whose own and inherited methods are to be returned\n   * @param typeUtils a {@link Types} object, typically returned by {@link\n   *     javax.annotation.processing.AbstractProcessor#processingEnv processingEnv}.{@link\n   *     javax.annotation.processing.ProcessingEnvironment#getTypeUtils getTypeUtils()}\n   * @param elementUtils an {@link Elements} object, typically returned by {@link\n   *     javax.annotation.processing.AbstractProcessor#processingEnv processingEnv}.{@link\n   *     javax.annotation.processing.ProcessingEnvironment#getElementUtils getElementUtils()}\n   */\n  public static ImmutableSet<ExecutableElement> getLocalAndInheritedMethods(\n      TypeElement type, Types typeUtils, Elements elementUtils) {\n    return getLocalAndInheritedMethods(type, new ExplicitOverrides(typeUtils));\n  }\n\n  private static ImmutableSet<ExecutableElement> getLocalAndInheritedMethods(\n      TypeElement type, Overrides overrides) {\n    PackageElement pkg = getPackage(type);\n\n    ImmutableSet.Builder<ExecutableElement> methods = ImmutableSet.builder();\n    for (ExecutableElement method : getAllMethods(type, overrides)) {\n      // Filter out all static and non-visible methods.\n      if (!method.getModifiers().contains(STATIC) && methodVisibleFromPackage(method, pkg)) {\n        methods.add(method);\n      }\n    }\n    return methods.build();\n  }\n\n  /**\n   * Tests whether one method, as a member of a given type, overrides another method.\n   *\n   * <p>This method does the same thing as {@link Elements#overrides(ExecutableElement,\n   * ExecutableElement, TypeElement)}, but in a way that is more consistent between compilers, in\n   * particular between javac and ecj (the Eclipse compiler).\n   *\n   * @param overrider the first method, possible overrider\n   * @param overridden the second method, possibly being overridden\n   * @param type the type of which the first method is a member\n   * @return {@code true} if and only if the first method overrides the second\n   */\n  public static boolean overrides(\n      ExecutableElement overrider,\n      ExecutableElement overridden,\n      TypeElement type,\n      Types typeUtils) {\n    return new ExplicitOverrides(typeUtils).overrides(overrider, overridden, type);\n  }\n\n  /**\n   * Returns the set of all methods from {@code type}, including methods that it inherits from its\n   * ancestors. Inherited methods that are overridden are not included in the result. So if {@code\n   * type} defines {@code public String toString()}, the returned set will contain that method, but\n   * not the {@code toString()} method defined by {@code Object}.\n   *\n   * <p>The returned set may contain more than one method with the same signature, if {@code type}\n   * inherits those methods from different ancestors. For example, if it inherits from unrelated\n   * interfaces {@code One} and {@code Two} which each define {@code void foo();}, and if it does\n   * not itself override the {@code foo()} method, then both {@code One.foo()} and {@code Two.foo()}\n   * will be in the returned set.\n   *\n   * <p>The order of the returned set is deterministic: within a class or interface, methods are in\n   * the order they appear in the source code; methods in ancestors come before methods in\n   * descendants; methods in interfaces come before methods in classes; and in a class or interface\n   * that has more than one superinterface, the interfaces are in the order of their appearance in\n   * {@code implements} or {@code extends}.\n   *\n   * @param type the type whose own and inherited methods are to be returned\n   * @param typeUtils a {@link Types} object, typically returned by {@link\n   *     javax.annotation.processing.AbstractProcessor#processingEnv processingEnv}.{@link\n   *     javax.annotation.processing.ProcessingEnvironment#getTypeUtils getTypeUtils()}\n   * @param elementUtils an {@link Elements} object, typically returned by {@link\n   *     javax.annotation.processing.AbstractProcessor#processingEnv processingEnv}.{@link\n   *     javax.annotation.processing.ProcessingEnvironment#getElementUtils getElementUtils()}\n   */\n  public static ImmutableSet<ExecutableElement> getAllMethods(\n      TypeElement type, Types typeUtils, Elements elementUtils) {\n    return getAllMethods(type, new ExplicitOverrides(typeUtils));\n  }\n\n  private static ImmutableSet<ExecutableElement> getAllMethods(\n      TypeElement type, Overrides overrides) {\n    SetMultimap<String, ExecutableElement> methodMap = LinkedHashMultimap.create();\n    getAllMethods(type, methodMap);\n    // Find methods that are overridden. We do this using `Elements.overrides`, which means\n    // that it is inherently a quadratic operation, since we have to compare every method against\n    // every other method. We reduce the performance impact by (a) grouping methods by name, since\n    // a method cannot override another method with a different name, and (b) making sure that\n    // methods in ancestor types precede those in descendant types, which means we only have to\n    // check a method against the ones that follow it in that order.\n    Set<ExecutableElement> overridden = new LinkedHashSet<ExecutableElement>();\n    for (Collection<ExecutableElement> methods : methodMap.asMap().values()) {\n      List<ExecutableElement> methodList = ImmutableList.copyOf(methods);\n      for (int i = 0; i < methodList.size(); i++) {\n        ExecutableElement methodI = methodList.get(i);\n        for (int j = i + 1; j < methodList.size(); j++) {\n          ExecutableElement methodJ = methodList.get(j);\n          if (overrides.overrides(methodJ, methodI, type)) {\n            overridden.add(methodI);\n            break;\n          }\n        }\n      }\n    }\n    return methodMap.values().stream()\n        .filter(m -> !overridden.contains(m))\n        .collect(toImmutableSet());\n  }\n\n  // Add to `methods` the static and instance methods from `type`. This means all methods from\n  // `type` itself and all methods it inherits from its ancestors. This method does not take\n  // overriding into account, so it will add both an ancestor method and a descendant method that\n  // overrides it. `methods` is a multimap from a method name to all of the methods with that name,\n  // including methods that override or overload one another. Within those methods, those in\n  // ancestor types always precede those in descendant types.\n  private static void getAllMethods(\n      TypeElement type, SetMultimap<String, ExecutableElement> methods) {\n    for (TypeMirror superInterface : type.getInterfaces()) {\n      getAllMethods(MoreTypes.asTypeElement(superInterface), methods);\n    }\n    if (type.getSuperclass().getKind() != TypeKind.NONE) {\n      // Visit the superclass after superinterfaces so we will always see the implementation of a\n      // method after any interfaces that declared it.\n      getAllMethods(MoreTypes.asTypeElement(type.getSuperclass()), methods);\n    }\n    for (ExecutableElement method : ElementFilter.methodsIn(type.getEnclosedElements())) {\n      methods.put(method.getSimpleName().toString(), method);\n    }\n  }\n\n  static boolean methodVisibleFromPackage(ExecutableElement method, PackageElement pkg) {\n    // We use Visibility.ofElement rather than .effectiveVisibilityOfElement because it doesn't\n    // really matter whether the containing class is visible. If you inherit a public method\n    // then you have a public method, regardless of whether you inherit it from a public class.\n    Visibility visibility = Visibility.ofElement(method);\n    switch (visibility) {\n      case PRIVATE:\n        return false;\n      case DEFAULT:\n        return getPackage(method).equals(pkg);\n      default:\n        return true;\n    }\n  }\n\n  private abstract static class CastingElementVisitor<T> extends SimpleElementVisitor8<T, Void> {\n    private final String label;\n\n    CastingElementVisitor(String label) {\n      this.label = label;\n    }\n\n    @Override\n    protected final T defaultAction(Element e, Void ignore) {\n      throw new IllegalArgumentException(e + \" does not represent a \" + label);\n    }\n  }\n\n  private MoreElements() {}\n}\n"
  },
  {
    "path": "common/src/main/java/com/google/auto/common/MoreStreams.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.auto.common;\n\nimport static java.util.stream.Collectors.collectingAndThen;\nimport static java.util.stream.Collectors.toList;\n\nimport com.google.common.collect.ImmutableBiMap;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Maps;\nimport java.util.Map;\nimport java.util.function.Function;\nimport java.util.stream.Collector;\nimport java.util.stream.Collectors;\n\n/**\n * A utility class that provides legacy alternatives to Guava's streaming APIs.\n *\n * <p>This class was useful when those APIs were not part of the Android flavor of Guava, since the\n * Android flavor somehow finds its way onto the processor classpath. Now that the APIs are part of\n * the Android flavor of Guava, there is no need for this class.\n */\npublic final class MoreStreams {\n\n  /** Returns a collector for an {@link ImmutableList}. */\n  public static <T> Collector<T, ?, ImmutableList<T>> toImmutableList() {\n    return collectingAndThen(toList(), ImmutableList::copyOf);\n  }\n\n  /** Returns a collector for an {@link ImmutableSet}. */\n  public static <T> Collector<T, ?, ImmutableSet<T>> toImmutableSet() {\n    return collectingAndThen(toList(), ImmutableSet::copyOf);\n  }\n\n  /** Returns a collector for an {@link ImmutableMap}. */\n  public static <T, K, V> Collector<T, ?, ImmutableMap<K, V>> toImmutableMap(\n      Function<? super T, K> keyMapper, Function<? super T, V> valueMapper) {\n    return Collectors.mapping(\n        value -> Maps.immutableEntry(keyMapper.apply(value), valueMapper.apply(value)),\n        Collector.of(\n            ImmutableMap::builder,\n            (ImmutableMap.Builder<K, V> builder, Map.Entry<K, V> entry) -> builder.put(entry),\n            (left, right) -> left.putAll(right.build()),\n            ImmutableMap.Builder::build));\n  }\n\n  /** Returns a collector for an {@link ImmutableBiMap}. */\n  public static <T, K, V> Collector<T, ?, ImmutableBiMap<K, V>> toImmutableBiMap(\n      Function<? super T, K> keyMapper, Function<? super T, V> valueMapper) {\n    return Collectors.mapping(\n        value -> Maps.immutableEntry(keyMapper.apply(value), valueMapper.apply(value)),\n        Collector.of(\n            ImmutableBiMap::builder,\n            (ImmutableBiMap.Builder<K, V> builder, Map.Entry<K, V> entry) -> builder.put(entry),\n            (left, right) -> left.putAll(right.build()),\n            ImmutableBiMap.Builder::build));\n  }\n\n  private MoreStreams() {}\n}\n"
  },
  {
    "path": "common/src/main/java/com/google/auto/common/MoreTypes.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport static com.google.common.base.Preconditions.checkNotNull;\nimport static com.google.common.base.Preconditions.checkState;\nimport static javax.lang.model.type.TypeKind.ARRAY;\nimport static javax.lang.model.type.TypeKind.DECLARED;\nimport static javax.lang.model.type.TypeKind.EXECUTABLE;\nimport static javax.lang.model.type.TypeKind.INTERSECTION;\nimport static javax.lang.model.type.TypeKind.TYPEVAR;\nimport static javax.lang.model.type.TypeKind.WILDCARD;\n\nimport com.google.common.base.Equivalence;\nimport com.google.common.base.Optional;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Set;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ElementKind;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.Modifier;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.TypeParameterElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.ArrayType;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.ErrorType;\nimport javax.lang.model.type.ExecutableType;\nimport javax.lang.model.type.IntersectionType;\nimport javax.lang.model.type.NoType;\nimport javax.lang.model.type.NullType;\nimport javax.lang.model.type.PrimitiveType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.type.TypeVariable;\nimport javax.lang.model.type.WildcardType;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.SimpleTypeVisitor8;\nimport javax.lang.model.util.Types;\nimport org.jspecify.annotations.Nullable;\n\n/**\n * Utilities related to {@link TypeMirror} instances.\n *\n * @author Gregory Kick\n * @since 2.0\n */\npublic final class MoreTypes {\n  private static final class TypeEquivalence extends Equivalence<TypeMirror> {\n    private static final TypeEquivalence INSTANCE = new TypeEquivalence();\n\n    @Override\n    protected boolean doEquivalent(TypeMirror a, TypeMirror b) {\n      return MoreTypes.equal(a, b, ImmutableSet.<ComparedElements>of());\n    }\n\n    @Override\n    protected int doHash(TypeMirror t) {\n      return MoreTypes.hash(t, ImmutableSet.<Element>of());\n    }\n\n    @Override\n    public String toString() {\n      return \"MoreTypes.equivalence()\";\n    }\n  }\n\n  /**\n   * Returns an {@link Equivalence} that can be used to compare types. The standard way to compare\n   * types is {@link javax.lang.model.util.Types#isSameType Types.isSameType}, but this alternative\n   * may be preferred in a number of cases:\n   *\n   * <ul>\n   *   <li>If you don't have an instance of {@code Types}.\n   *   <li>If you want a reliable {@code hashCode()} for the types, for example to construct a set\n   *       of types using {@link java.util.HashSet} with {@link Equivalence#wrap(Object)}.\n   *   <li>If you want distinct type variables to be considered equal if they have the same names\n   *       and bounds.\n   *   <li>If you want wildcard types to compare equal if they have the same bounds. {@code\n   *       Types.isSameType} never considers wildcards equal, even when comparing a type to itself.\n   * </ul>\n   */\n  public static Equivalence<TypeMirror> equivalence() {\n    return TypeEquivalence.INSTANCE;\n  }\n\n  // So EQUAL_VISITOR can be a singleton, we maintain visiting state, in particular which types\n  // have been seen already, in this object.\n  // The logic for handling recursive types like Comparable<T extends Comparable<T>> is very tricky.\n  // If we're not careful we'll end up with an infinite recursion. So we record the types that\n  // we've already seen during the recursion, and if we see the same pair of types again we just\n  // return true provisionally. But \"the same pair of types\" is itself poorly-defined. We can't\n  // just say that it is an equal pair of TypeMirrors, because of course if we knew how to\n  // determine that then we wouldn't need the complicated type visitor at all. On the other hand,\n  // we can't say that it is an identical pair of TypeMirrors either, because there's no\n  // guarantee that the TypeMirrors for the two Ts in Comparable<T extends Comparable<T>> will be\n  // represented by the same object, and indeed with the Eclipse compiler they aren't. We could\n  // compare the corresponding Elements, since equality is well-defined there, but that's not enough\n  // either, because the Element for Set<Object> is the same as the one for Set<String>. So we\n  // approximate by comparing the Elements and, if there are any type arguments, requiring them to\n  // be identical. This may not be foolproof either but it is sufficient for all the cases we've\n  // encountered so far.\n  private static final class EqualVisitorParam {\n    TypeMirror type;\n    Set<ComparedElements> visiting;\n  }\n\n  private static class ComparedElements {\n    final Element a;\n    final ImmutableList<TypeMirror> aArguments;\n    final Element b;\n    final ImmutableList<TypeMirror> bArguments;\n\n    ComparedElements(\n        Element a,\n        ImmutableList<TypeMirror> aArguments,\n        Element b,\n        ImmutableList<TypeMirror> bArguments) {\n      this.a = a;\n      this.aArguments = aArguments;\n      this.b = b;\n      this.bArguments = bArguments;\n    }\n\n    @Override\n    public boolean equals(@Nullable Object o) {\n      if (!(o instanceof ComparedElements)) {\n        return false;\n      }\n      ComparedElements that = (ComparedElements) o;\n\n      int nArguments = this.aArguments.size();\n      if (nArguments != that.aArguments.size()) {\n        return false;\n      }\n      // The arguments must be the same size, but we check anyway.\n      if (nArguments != this.bArguments.size() || nArguments != that.bArguments.size()) {\n        return false;\n      }\n\n      if (!this.a.equals(that.a) || !this.b.equals(that.b)) {\n        return false;\n      }\n\n      /*\n       * The purpose here is just to avoid the infinite recursion that we would otherwise have\n       * if Enum<E extends Enum<E>> is compared against itself, for example. If we are able to\n       * see that the inner Enum<E> is the same object as the outer one then we don't need a\n       * recursive call to compare the \"a\" Enum<E> against the \"b\" Enum<E>. The same-object check\n       * may not be completely justified, but it relies on the practical assumption that the\n       * compiler is not going to conjure up an infinite regress of objects to represent this\n       * recursive type. Other comparison methods like comparing their toString() are expensive\n       * and not warranted.\n       */\n      for (int i = 0; i < nArguments; i++) {\n        if (this.aArguments.get(i) != that.aArguments.get(i)) {\n          return false;\n        }\n        if (this.bArguments.get(i) != that.bArguments.get(i)) {\n          return false;\n        }\n      }\n\n      return true;\n    }\n\n    @Override\n    public int hashCode() {\n      return a.hashCode() * 31 + b.hashCode();\n    }\n  }\n\n  private static final class EqualVisitor extends SimpleTypeVisitor8<Boolean, EqualVisitorParam> {\n    private static final EqualVisitor INSTANCE = new EqualVisitor();\n\n    @Override\n    protected Boolean defaultAction(TypeMirror a, EqualVisitorParam p) {\n      return a.getKind().equals(p.type.getKind());\n    }\n\n    @Override\n    public Boolean visitArray(ArrayType a, EqualVisitorParam p) {\n      if (p.type.getKind().equals(ARRAY)) {\n        ArrayType b = (ArrayType) p.type;\n        return equal(a.getComponentType(), b.getComponentType(), p.visiting);\n      }\n      return false;\n    }\n\n    @Override\n    public Boolean visitDeclared(DeclaredType a, EqualVisitorParam p) {\n      if (p.type.getKind().equals(DECLARED)) {\n        DeclaredType b = (DeclaredType) p.type;\n        Element aElement = a.asElement();\n        Element bElement = b.asElement();\n        Set<ComparedElements> newVisiting =\n            visitingSetPlus(\n                p.visiting, aElement, a.getTypeArguments(), bElement, b.getTypeArguments());\n        if (newVisiting.equals(p.visiting)) {\n          // We're already visiting this pair of elements.\n          // This can happen for example with Enum in Enum<E extends Enum<E>>. Return a\n          // provisional true value since if the Elements are not in fact equal the original\n          // visitor of Enum will discover that. We have to check both Elements being compared\n          // though to avoid missing the fact that one of the types being compared\n          // differs at exactly this point.\n          return true;\n        }\n        return aElement.equals(bElement)\n            && equal(enclosingType(a), enclosingType(b), newVisiting)\n            && equalLists(a.getTypeArguments(), b.getTypeArguments(), newVisiting);\n      }\n      return false;\n    }\n\n    @Override\n    @SuppressWarnings(\"TypeEquals\")\n    public Boolean visitError(ErrorType a, EqualVisitorParam p) {\n      return a.equals(p.type);\n    }\n\n    @Override\n    public Boolean visitExecutable(ExecutableType a, EqualVisitorParam p) {\n      if (p.type.getKind().equals(EXECUTABLE)) {\n        ExecutableType b = (ExecutableType) p.type;\n        return equalLists(a.getParameterTypes(), b.getParameterTypes(), p.visiting)\n            && equal(a.getReturnType(), b.getReturnType(), p.visiting)\n            && equalLists(a.getThrownTypes(), b.getThrownTypes(), p.visiting)\n            && equalLists(a.getTypeVariables(), b.getTypeVariables(), p.visiting);\n      }\n      return false;\n    }\n\n    @Override\n    public Boolean visitIntersection(IntersectionType a, EqualVisitorParam p) {\n      if (p.type.getKind().equals(INTERSECTION)) {\n        IntersectionType b = (IntersectionType) p.type;\n        return equalLists(a.getBounds(), b.getBounds(), p.visiting);\n      }\n      return false;\n    }\n\n    @Override\n    public Boolean visitTypeVariable(TypeVariable a, EqualVisitorParam p) {\n      if (p.type.getKind().equals(TYPEVAR)) {\n        TypeVariable b = (TypeVariable) p.type;\n        TypeParameterElement aElement = (TypeParameterElement) a.asElement();\n        TypeParameterElement bElement = (TypeParameterElement) b.asElement();\n        Set<ComparedElements> newVisiting = visitingSetPlus(p.visiting, aElement, bElement);\n        if (newVisiting.equals(p.visiting)) {\n          // We're already visiting this pair of elements.\n          // This can happen with our friend Eclipse when looking at <T extends Comparable<T>>.\n          // It incorrectly reports the upper bound of T as T itself.\n          return true;\n        }\n        // We use aElement.getBounds() instead of a.getUpperBound() to avoid having to deal with\n        // the different way intersection types (like <T extends Number & Comparable<T>>) are\n        // represented before and after Java 8. We do have an issue that this code may consider\n        // that <T extends Foo & Bar> is different from <T extends Bar & Foo>, but it's very\n        // hard to avoid that, and not likely to be much of a problem in practice.\n        return equalLists(aElement.getBounds(), bElement.getBounds(), newVisiting)\n            && equal(a.getLowerBound(), b.getLowerBound(), newVisiting)\n            && a.asElement().getSimpleName().equals(b.asElement().getSimpleName());\n      }\n      return false;\n    }\n\n    @Override\n    public Boolean visitWildcard(WildcardType a, EqualVisitorParam p) {\n      if (p.type.getKind().equals(WILDCARD)) {\n        WildcardType b = (WildcardType) p.type;\n        return equal(a.getExtendsBound(), b.getExtendsBound(), p.visiting)\n            && equal(a.getSuperBound(), b.getSuperBound(), p.visiting);\n      }\n      return false;\n    }\n\n    @Override\n    public Boolean visitUnknown(TypeMirror a, EqualVisitorParam p) {\n      throw new UnsupportedOperationException();\n    }\n\n    private Set<ComparedElements> visitingSetPlus(\n        Set<ComparedElements> visiting, Element a, Element b) {\n      ImmutableList<TypeMirror> noArguments = ImmutableList.of();\n      return visitingSetPlus(visiting, a, noArguments, b, noArguments);\n    }\n\n    private Set<ComparedElements> visitingSetPlus(\n        Set<ComparedElements> visiting,\n        Element a,\n        List<? extends TypeMirror> aArguments,\n        Element b,\n        List<? extends TypeMirror> bArguments) {\n      ComparedElements comparedElements =\n          new ComparedElements(\n              a, ImmutableList.<TypeMirror>copyOf(aArguments),\n              b, ImmutableList.<TypeMirror>copyOf(bArguments));\n      Set<ComparedElements> newVisiting = new HashSet<ComparedElements>(visiting);\n      newVisiting.add(comparedElements);\n      return newVisiting;\n    }\n  }\n\n  @SuppressWarnings(\"TypeEquals\")\n  private static boolean equal(\n      @Nullable TypeMirror a, @Nullable TypeMirror b, Set<ComparedElements> visiting) {\n    if (a == b) {\n      return true;\n    }\n    if (a == null || b == null) {\n      return false;\n    }\n    // TypeMirror.equals is not guaranteed to return true for types that are equal, but we can\n    // assume that if it does return true then the types are equal. This check also avoids getting\n    // stuck in infinite recursion when Eclipse decrees that the upper bound of the second K in\n    // <K extends Comparable<K>> is a distinct but equal K.\n    // The javac implementation of ExecutableType, at least in some versions, does not take thrown\n    // exceptions into account in its equals implementation, so avoid this optimization for\n    // ExecutableType.\n    @SuppressWarnings(\"TypesEquals\")\n    boolean equal = a.equals(b);\n    if (equal && a.getKind() != TypeKind.EXECUTABLE) {\n      return true;\n    }\n    EqualVisitorParam p = new EqualVisitorParam();\n    p.type = b;\n    p.visiting = visiting;\n    return a.accept(EqualVisitor.INSTANCE, p);\n  }\n\n  /**\n   * Returns the type of the innermost enclosing instance, or null if there is none. This is the\n   * same as {@link DeclaredType#getEnclosingType()} except that it returns null rather than NoType\n   * for a static type. We need this because of <a\n   * href=\"https://bugs.eclipse.org/bugs/show_bug.cgi?id=508222\">this bug</a> whereby the Eclipse\n   * compiler returns a value for static classes that is not NoType.\n   */\n  private static @Nullable TypeMirror enclosingType(DeclaredType t) {\n    TypeMirror enclosing = t.getEnclosingType();\n    if (enclosing.getKind().equals(TypeKind.NONE)\n        || t.asElement().getModifiers().contains(Modifier.STATIC)) {\n      return null;\n    }\n    return enclosing;\n  }\n\n  private static boolean equalLists(\n      List<? extends TypeMirror> a, List<? extends TypeMirror> b, Set<ComparedElements> visiting) {\n    int size = a.size();\n    if (size != b.size()) {\n      return false;\n    }\n    // Use iterators in case the Lists aren't RandomAccess\n    Iterator<? extends TypeMirror> aIterator = a.iterator();\n    Iterator<? extends TypeMirror> bIterator = b.iterator();\n    while (aIterator.hasNext()) {\n      // We checked that the lists have the same size, so we know that bIterator.hasNext() too.\n      TypeMirror nextMirrorA = aIterator.next();\n      TypeMirror nextMirrorB = bIterator.next();\n      if (!equal(nextMirrorA, nextMirrorB, visiting)) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  private static final int HASH_SEED = 17;\n  private static final int HASH_MULTIPLIER = 31;\n\n  private static final class HashVisitor extends SimpleTypeVisitor8<Integer, Set<Element>> {\n    private static final HashVisitor INSTANCE = new HashVisitor();\n\n    int hashKind(int seed, TypeMirror t) {\n      int result = seed * HASH_MULTIPLIER;\n      result += t.getKind().hashCode();\n      return result;\n    }\n\n    @Override\n    protected Integer defaultAction(TypeMirror e, Set<Element> visiting) {\n      return hashKind(HASH_SEED, e);\n    }\n\n    @Override\n    public Integer visitArray(ArrayType t, Set<Element> visiting) {\n      int result = hashKind(HASH_SEED, t);\n      result *= HASH_MULTIPLIER;\n      result += t.getComponentType().accept(this, visiting);\n      return result;\n    }\n\n    @Override\n    public Integer visitDeclared(DeclaredType t, Set<Element> visiting) {\n      Element element = t.asElement();\n      if (visiting.contains(element)) {\n        return 0;\n      }\n      Set<Element> newVisiting = new HashSet<Element>(visiting);\n      newVisiting.add(element);\n      int result = hashKind(HASH_SEED, t);\n      result *= HASH_MULTIPLIER;\n      result += t.asElement().hashCode();\n      result *= HASH_MULTIPLIER;\n      result += t.getEnclosingType().accept(this, newVisiting);\n      result *= HASH_MULTIPLIER;\n      result += hashList(t.getTypeArguments(), newVisiting);\n      return result;\n    }\n\n    @Override\n    public Integer visitExecutable(ExecutableType t, Set<Element> visiting) {\n      int result = hashKind(HASH_SEED, t);\n      result *= HASH_MULTIPLIER;\n      result += hashList(t.getParameterTypes(), visiting);\n      result *= HASH_MULTIPLIER;\n      result += t.getReturnType().accept(this, visiting);\n      result *= HASH_MULTIPLIER;\n      result += hashList(t.getThrownTypes(), visiting);\n      result *= HASH_MULTIPLIER;\n      result += hashList(t.getTypeVariables(), visiting);\n      return result;\n    }\n\n    @Override\n    public Integer visitTypeVariable(TypeVariable t, Set<Element> visiting) {\n      int result = hashKind(HASH_SEED, t);\n      result *= HASH_MULTIPLIER;\n      result += t.getLowerBound().accept(this, visiting);\n      TypeParameterElement element = (TypeParameterElement) t.asElement();\n      for (TypeMirror bound : element.getBounds()) {\n        result *= HASH_MULTIPLIER;\n        result += bound.accept(this, visiting);\n      }\n      return result;\n    }\n\n    @Override\n    public Integer visitWildcard(WildcardType t, Set<Element> visiting) {\n      int result = hashKind(HASH_SEED, t);\n      result *= HASH_MULTIPLIER;\n      result += (t.getExtendsBound() == null) ? 0 : t.getExtendsBound().accept(this, visiting);\n      result *= HASH_MULTIPLIER;\n      result += (t.getSuperBound() == null) ? 0 : t.getSuperBound().accept(this, visiting);\n      return result;\n    }\n\n    @Override\n    public Integer visitUnknown(TypeMirror t, Set<Element> visiting) {\n      throw new UnsupportedOperationException();\n    }\n  }\n\n  private static int hashList(List<? extends TypeMirror> mirrors, Set<Element> visiting) {\n    int result = HASH_SEED;\n    for (TypeMirror mirror : mirrors) {\n      result *= HASH_MULTIPLIER;\n      result += hash(mirror, visiting);\n    }\n    return result;\n  }\n\n  private static int hash(TypeMirror mirror, Set<Element> visiting) {\n    return mirror == null ? 0 : mirror.accept(HashVisitor.INSTANCE, visiting);\n  }\n\n  /**\n   * Returns the set of {@linkplain TypeElement types} that are referenced by the given {@link\n   * TypeMirror}.\n   */\n  public static ImmutableSet<TypeElement> referencedTypes(TypeMirror type) {\n    checkNotNull(type);\n    ImmutableSet.Builder<TypeElement> elements = ImmutableSet.builder();\n    type.accept(ReferencedTypes.INSTANCE, elements);\n    return elements.build();\n  }\n\n  private static final class ReferencedTypes\n      extends SimpleTypeVisitor8<@Nullable Void, ImmutableSet.Builder<TypeElement>> {\n    private static final ReferencedTypes INSTANCE = new ReferencedTypes();\n\n    @Override\n    public @Nullable Void visitArray(ArrayType t, ImmutableSet.Builder<TypeElement> p) {\n      t.getComponentType().accept(this, p);\n      return null;\n    }\n\n    @Override\n    public @Nullable Void visitDeclared(DeclaredType t, ImmutableSet.Builder<TypeElement> p) {\n      p.add(MoreElements.asType(t.asElement()));\n      for (TypeMirror typeArgument : t.getTypeArguments()) {\n        typeArgument.accept(this, p);\n      }\n      return null;\n    }\n\n    @Override\n    public @Nullable Void visitTypeVariable(TypeVariable t, ImmutableSet.Builder<TypeElement> p) {\n      t.getLowerBound().accept(this, p);\n      t.getUpperBound().accept(this, p);\n      return null;\n    }\n\n    @Override\n    public @Nullable Void visitWildcard(WildcardType t, ImmutableSet.Builder<TypeElement> p) {\n      TypeMirror extendsBound = t.getExtendsBound();\n      if (extendsBound != null) {\n        extendsBound.accept(this, p);\n      }\n      TypeMirror superBound = t.getSuperBound();\n      if (superBound != null) {\n        superBound.accept(this, p);\n      }\n      return null;\n    }\n  }\n\n  /**\n   * An alternate implementation of {@link Types#asElement} that does not require a {@link Types}\n   * instance with the notable difference that it will throw {@link IllegalArgumentException}\n   * instead of returning null if the {@link TypeMirror} can not be converted to an {@link Element}.\n   *\n   * @throws NullPointerException if {@code typeMirror} is {@code null}\n   * @throws IllegalArgumentException if {@code typeMirror} cannot be converted to an {@link\n   *     Element}\n   */\n  public static Element asElement(TypeMirror typeMirror) {\n    return typeMirror.accept(AsElementVisitor.INSTANCE, null);\n  }\n\n  private static final class AsElementVisitor extends SimpleTypeVisitor8<Element, Void> {\n    private static final AsElementVisitor INSTANCE = new AsElementVisitor();\n\n    @Override\n    protected Element defaultAction(TypeMirror e, Void p) {\n      throw new IllegalArgumentException(e + \" cannot be converted to an Element\");\n    }\n\n    @Override\n    public Element visitDeclared(DeclaredType t, Void p) {\n      return t.asElement();\n    }\n\n    @Override\n    public Element visitError(ErrorType t, Void p) {\n      return t.asElement();\n    }\n\n    @Override\n    public Element visitTypeVariable(TypeVariable t, Void p) {\n      return t.asElement();\n    }\n  }\n  ;\n\n  // TODO(gak): consider removing these two methods as they're pretty trivial now\n  public static TypeElement asTypeElement(TypeMirror mirror) {\n    return MoreElements.asType(asElement(mirror));\n  }\n\n  public static ImmutableSet<TypeElement> asTypeElements(Iterable<? extends TypeMirror> mirrors) {\n    checkNotNull(mirrors);\n    ImmutableSet.Builder<TypeElement> builder = ImmutableSet.builder();\n    for (TypeMirror mirror : mirrors) {\n      builder.add(asTypeElement(mirror));\n    }\n    return builder.build();\n  }\n\n  /**\n   * Returns a {@link ArrayType} if the {@link TypeMirror} represents an array or throws an {@link\n   * IllegalArgumentException}.\n   */\n  public static ArrayType asArray(TypeMirror maybeArrayType) {\n    return maybeArrayType.accept(ArrayTypeVisitor.INSTANCE, null);\n  }\n\n  private static final class ArrayTypeVisitor extends CastingTypeVisitor<ArrayType> {\n    private static final ArrayTypeVisitor INSTANCE = new ArrayTypeVisitor();\n\n    ArrayTypeVisitor() {\n      super(\"array\");\n    }\n\n    @Override\n    public ArrayType visitArray(ArrayType type, Void ignore) {\n      return type;\n    }\n  }\n\n  /**\n   * Returns a {@link DeclaredType} if the {@link TypeMirror} represents a declared type such as a\n   * class, interface, union/compound, or enum or throws an {@link IllegalArgumentException}.\n   */\n  public static DeclaredType asDeclared(TypeMirror maybeDeclaredType) {\n    return maybeDeclaredType.accept(DeclaredTypeVisitor.INSTANCE, null);\n  }\n\n  private static final class DeclaredTypeVisitor extends CastingTypeVisitor<DeclaredType> {\n    private static final DeclaredTypeVisitor INSTANCE = new DeclaredTypeVisitor();\n\n    DeclaredTypeVisitor() {\n      super(\"declared type\");\n    }\n\n    @Override\n    public DeclaredType visitDeclared(DeclaredType type, Void ignore) {\n      return type;\n    }\n  }\n\n  /**\n   * Returns a {@link ExecutableType} if the {@link TypeMirror} represents an executable type such\n   * as may result from missing code, or bad compiles or throws an {@link IllegalArgumentException}.\n   */\n  public static ErrorType asError(TypeMirror maybeErrorType) {\n    return maybeErrorType.accept(ErrorTypeVisitor.INSTANCE, null);\n  }\n\n  private static final class ErrorTypeVisitor extends CastingTypeVisitor<ErrorType> {\n    private static final ErrorTypeVisitor INSTANCE = new ErrorTypeVisitor();\n\n    ErrorTypeVisitor() {\n      super(\"error type\");\n    }\n\n    @Override\n    public ErrorType visitError(ErrorType type, Void ignore) {\n      return type;\n    }\n  }\n\n  /**\n   * Returns a {@link ExecutableType} if the {@link TypeMirror} represents an executable type such\n   * as a method, constructor, or initializer or throws an {@link IllegalArgumentException}.\n   */\n  public static ExecutableType asExecutable(TypeMirror maybeExecutableType) {\n    return maybeExecutableType.accept(ExecutableTypeVisitor.INSTANCE, null);\n  }\n\n  private static final class ExecutableTypeVisitor extends CastingTypeVisitor<ExecutableType> {\n    private static final ExecutableTypeVisitor INSTANCE = new ExecutableTypeVisitor();\n\n    ExecutableTypeVisitor() {\n      super(\"executable type\");\n    }\n\n    @Override\n    public ExecutableType visitExecutable(ExecutableType type, Void ignore) {\n      return type;\n    }\n  }\n\n  /**\n   * Returns an {@link IntersectionType} if the {@link TypeMirror} represents an intersection-type\n   * or throws an {@link IllegalArgumentException}.\n   */\n  public static IntersectionType asIntersection(TypeMirror maybeIntersectionType) {\n    return maybeIntersectionType.accept(IntersectionTypeVisitor.INSTANCE, null);\n  }\n\n  private static final class IntersectionTypeVisitor extends CastingTypeVisitor<IntersectionType> {\n    private static final IntersectionTypeVisitor INSTANCE = new IntersectionTypeVisitor();\n\n    IntersectionTypeVisitor() {\n      super(\"intersection type\");\n    }\n\n    @Override\n    public IntersectionType visitIntersection(IntersectionType type, Void ignore) {\n      return type;\n    }\n  }\n\n  /**\n   * Returns a {@link NoType} if the {@link TypeMirror} represents an non-type such as void, or\n   * package, etc. or throws an {@link IllegalArgumentException}.\n   */\n  public static NoType asNoType(TypeMirror maybeNoType) {\n    return maybeNoType.accept(NoTypeVisitor.INSTANCE, null);\n  }\n\n  private static final class NoTypeVisitor extends CastingTypeVisitor<NoType> {\n    private static final NoTypeVisitor INSTANCE = new NoTypeVisitor();\n\n    NoTypeVisitor() {\n      super(\"non-type\");\n    }\n\n    @Override\n    public NoType visitNoType(NoType type, Void ignore) {\n      return type;\n    }\n  }\n\n  /**\n   * Returns a {@link NullType} if the {@link TypeMirror} represents the null type or throws an\n   * {@link IllegalArgumentException}.\n   */\n  public static NullType asNullType(TypeMirror maybeNullType) {\n    return maybeNullType.accept(NullTypeVisitor.INSTANCE, null);\n  }\n\n  private static final class NullTypeVisitor extends CastingTypeVisitor<NullType> {\n    private static final NullTypeVisitor INSTANCE = new NullTypeVisitor();\n\n    NullTypeVisitor() {\n      super(\"null\");\n    }\n\n    @Override\n    public NullType visitNull(NullType type, Void ignore) {\n      return type;\n    }\n  }\n\n  /**\n   * Returns a {@link PrimitiveType} if the {@link TypeMirror} represents a primitive type or throws\n   * an {@link IllegalArgumentException}.\n   */\n  public static PrimitiveType asPrimitiveType(TypeMirror maybePrimitiveType) {\n    return maybePrimitiveType.accept(PrimitiveTypeVisitor.INSTANCE, null);\n  }\n\n  private static final class PrimitiveTypeVisitor extends CastingTypeVisitor<PrimitiveType> {\n    private static final PrimitiveTypeVisitor INSTANCE = new PrimitiveTypeVisitor();\n\n    PrimitiveTypeVisitor() {\n      super(\"primitive type\");\n    }\n\n    @Override\n    public PrimitiveType visitPrimitive(PrimitiveType type, Void ignore) {\n      return type;\n    }\n  }\n\n  //\n  // visitUnionType would go here, but isn't relevant for annotation processors\n  //\n\n  /**\n   * Returns a {@link TypeVariable} if the {@link TypeMirror} represents a type variable or throws\n   * an {@link IllegalArgumentException}.\n   */\n  public static TypeVariable asTypeVariable(TypeMirror maybeTypeVariable) {\n    return maybeTypeVariable.accept(TypeVariableVisitor.INSTANCE, null);\n  }\n\n  private static final class TypeVariableVisitor extends CastingTypeVisitor<TypeVariable> {\n    private static final TypeVariableVisitor INSTANCE = new TypeVariableVisitor();\n\n    TypeVariableVisitor() {\n      super(\"type variable\");\n    }\n\n    @Override\n    public TypeVariable visitTypeVariable(TypeVariable type, Void ignore) {\n      return type;\n    }\n  }\n\n  /**\n   * Returns a {@link WildcardType} if the {@link TypeMirror} represents a wildcard type or throws\n   * an {@link IllegalArgumentException}.\n   */\n  public static WildcardType asWildcard(TypeMirror maybeWildcardType) {\n    return maybeWildcardType.accept(WildcardTypeVisitor.INSTANCE, null);\n  }\n\n  private static final class WildcardTypeVisitor extends CastingTypeVisitor<WildcardType> {\n    private static final WildcardTypeVisitor INSTANCE = new WildcardTypeVisitor();\n\n    WildcardTypeVisitor() {\n      super(\"wildcard type\");\n    }\n\n    @Override\n    public WildcardType visitWildcard(WildcardType type, Void ignore) {\n      return type;\n    }\n  }\n\n  /**\n   * Returns true if the raw type underlying the given {@link TypeMirror} represents a type that can\n   * be referenced by a {@link Class}. If this returns true, then {@link #isTypeOf} is guaranteed to\n   * not throw.\n   */\n  public static boolean isType(TypeMirror type) {\n    return type.accept(IsTypeVisitor.INSTANCE, null);\n  }\n\n  private static final class IsTypeVisitor extends SimpleTypeVisitor8<Boolean, Void> {\n    private static final IsTypeVisitor INSTANCE = new IsTypeVisitor();\n\n    @Override\n    protected Boolean defaultAction(TypeMirror type, Void ignored) {\n      return false;\n    }\n\n    @Override\n    public Boolean visitNoType(NoType noType, Void p) {\n      return noType.getKind().equals(TypeKind.VOID);\n    }\n\n    @Override\n    public Boolean visitPrimitive(PrimitiveType type, Void p) {\n      return true;\n    }\n\n    @Override\n    public Boolean visitArray(ArrayType array, Void p) {\n      return true;\n    }\n\n    @Override\n    public Boolean visitDeclared(DeclaredType type, Void ignored) {\n      return MoreElements.isType(type.asElement());\n    }\n  }\n\n  /**\n   * Returns true if the raw type underlying the given {@link TypeMirror} represents the same raw\n   * type as the given {@link Class} and throws an IllegalArgumentException if the {@link\n   * TypeMirror} does not represent a type that can be referenced by a {@link Class}\n   */\n  public static boolean isTypeOf(final Class<?> clazz, TypeMirror type) {\n    checkNotNull(clazz);\n    return type.accept(new IsTypeOf(clazz), null);\n  }\n\n  private static final class IsTypeOf extends SimpleTypeVisitor8<Boolean, Void> {\n    private final Class<?> clazz;\n\n    IsTypeOf(Class<?> clazz) {\n      this.clazz = clazz;\n    }\n\n    @Override\n    protected Boolean defaultAction(TypeMirror type, Void ignored) {\n      throw new IllegalArgumentException(type + \" cannot be represented as a Class<?>.\");\n    }\n\n    @Override\n    public Boolean visitNoType(NoType noType, Void p) {\n      if (noType.getKind().equals(TypeKind.VOID)) {\n        return clazz.equals(Void.TYPE);\n      }\n      throw new IllegalArgumentException(noType + \" cannot be represented as a Class<?>.\");\n    }\n\n    @Override\n    public Boolean visitError(ErrorType errorType, Void p) {\n      return false;\n    }\n\n    @Override\n    public Boolean visitPrimitive(PrimitiveType type, Void p) {\n      switch (type.getKind()) {\n        case BOOLEAN:\n          return clazz.equals(Boolean.TYPE);\n        case BYTE:\n          return clazz.equals(Byte.TYPE);\n        case CHAR:\n          return clazz.equals(Character.TYPE);\n        case DOUBLE:\n          return clazz.equals(Double.TYPE);\n        case FLOAT:\n          return clazz.equals(Float.TYPE);\n        case INT:\n          return clazz.equals(Integer.TYPE);\n        case LONG:\n          return clazz.equals(Long.TYPE);\n        case SHORT:\n          return clazz.equals(Short.TYPE);\n        default:\n          throw new IllegalArgumentException(type + \" cannot be represented as a Class<?>.\");\n      }\n    }\n\n    @Override\n    public Boolean visitArray(ArrayType array, Void p) {\n      return clazz.isArray() && isTypeOf(clazz.getComponentType(), array.getComponentType());\n    }\n\n    @Override\n    public Boolean visitDeclared(DeclaredType type, Void ignored) {\n      TypeElement typeElement = MoreElements.asType(type.asElement());\n      return typeElement.getQualifiedName().contentEquals(clazz.getCanonicalName());\n    }\n  }\n\n  /**\n   * Returns the superclass of {@code type}, with any type parameters bound by {@code type}, or\n   * {@link Optional#absent()} if {@code type} is an interface or {@link Object} or its superclass\n   * is {@link Object}.\n   */\n  // TODO(bcorso): Remove unused parameter Elements?\n  public static Optional<DeclaredType> nonObjectSuperclass(\n      Types types, Elements elements, DeclaredType type) {\n    checkNotNull(types);\n    checkNotNull(elements); // This is no longer used, but here to avoid changing the API.\n    checkNotNull(type);\n\n    TypeMirror superclassType = asTypeElement(type).getSuperclass();\n    if (!isType(superclassType)) { // type is Object or an interface\n      return Optional.absent();\n    }\n\n    DeclaredType superclass = asDeclared(superclassType);\n    if (isObjectType(superclass)) {\n      return Optional.absent();\n    }\n\n    if (superclass.getTypeArguments().isEmpty()) {\n      return Optional.of(superclass);\n    }\n\n    // In the case where the super class has type parameters, TypeElement#getSuperclass gives\n    // SuperClass<T> rather than SuperClass<Foo>, so use Types#directSupertypes instead. The javadoc\n    // for Types#directSupertypes guarantees that a super class, if it exists, comes before any\n    // interfaces. Thus, we can just get the first element in the list.\n    return Optional.of(asDeclared(types.directSupertypes(type).get(0)));\n  }\n\n  private static boolean isObjectType(DeclaredType type) {\n    return asTypeElement(type).getQualifiedName().contentEquals(\"java.lang.Object\");\n  }\n\n  /**\n   * Resolves a {@link VariableElement} parameter to a method or constructor based on the given\n   * container, or a member of a class. For parameters to a method or constructor, the variable's\n   * enclosing element must be a supertype of the container type. For example, given a {@code\n   * container} of type {@code Set<String>}, and a variable corresponding to the {@code E e}\n   * parameter in the {@code Set.add(E e)} method, this will return a TypeMirror for {@code String}.\n   */\n  public static TypeMirror asMemberOf(\n      Types types, DeclaredType container, VariableElement variable) {\n    if (variable.getKind().equals(ElementKind.PARAMETER)) {\n      ExecutableElement methodOrConstructor =\n          MoreElements.asExecutable(variable.getEnclosingElement());\n      ExecutableType resolvedMethodOrConstructor =\n          MoreTypes.asExecutable(types.asMemberOf(container, methodOrConstructor));\n      List<? extends VariableElement> parameters = methodOrConstructor.getParameters();\n      List<? extends TypeMirror> parameterTypes = resolvedMethodOrConstructor.getParameterTypes();\n      checkState(parameters.size() == parameterTypes.size());\n      for (int i = 0; i < parameters.size(); i++) {\n        // We need to capture the parameter type of the variable we're concerned about,\n        // for later printing.  This is the only way to do it since we can't use\n        // types.asMemberOf on variables of methods.\n        if (parameters.get(i).equals(variable)) {\n          return parameterTypes.get(i);\n        }\n      }\n      throw new IllegalStateException(\"Could not find variable: \" + variable);\n    } else {\n      return types.asMemberOf(container, variable);\n    }\n  }\n\n  private abstract static class CastingTypeVisitor<T> extends SimpleTypeVisitor8<T, Void> {\n    private final String label;\n\n    CastingTypeVisitor(String label) {\n      this.label = label;\n    }\n\n    @Override\n    protected T defaultAction(TypeMirror e, Void v) {\n      throw new IllegalArgumentException(e + \" does not represent a \" + label);\n    }\n  }\n\n  /**\n   * Returns true if casting {@code Object} to the given type will elicit an unchecked warning from\n   * the compiler. Only type variables and parameterized types such as {@code List<String>} produce\n   * such warnings. There will be no warning if the type's only type parameters are simple\n   * wildcards, as in {@code Map<?, ?>}.\n   */\n  public static boolean isConversionFromObjectUnchecked(TypeMirror type) {\n    return new CastingUncheckedVisitor().visit(type, null);\n  }\n\n  /**\n   * Visitor that tells whether a type is erased, in the sense of {@link #castIsUnchecked}. Each\n   * visitX method returns true if its input parameter is true or if the type being visited is\n   * erased.\n   */\n  private static class CastingUncheckedVisitor extends SimpleTypeVisitor8<Boolean, Void> {\n    CastingUncheckedVisitor() {\n      super(false);\n    }\n\n    @Override\n    public Boolean visitUnknown(TypeMirror t, Void p) {\n      // We don't know whether casting is unchecked for this mysterious type but assume it is,\n      // so we will insert a possibly unnecessary @SuppressWarnings(\"unchecked\").\n      return true;\n    }\n\n    @Override\n    public Boolean visitArray(ArrayType t, Void p) {\n      return visit(t.getComponentType(), p);\n    }\n\n    @Override\n    public Boolean visitDeclared(DeclaredType t, Void p) {\n      return t.getTypeArguments().stream().anyMatch(CastingUncheckedVisitor::uncheckedTypeArgument);\n    }\n\n    @Override\n    public Boolean visitTypeVariable(TypeVariable t, Void p) {\n      return true;\n    }\n\n    // If a type has a type argument, then casting to the type is unchecked, except if the argument\n    // is <?> or <? extends Object>. The same applies to all type arguments, so casting to Map<?, ?>\n    // does not produce an unchecked warning for example.\n    private static boolean uncheckedTypeArgument(TypeMirror arg) {\n      if (arg.getKind().equals(TypeKind.WILDCARD)) {\n        WildcardType wildcard = asWildcard(arg);\n        if (wildcard.getExtendsBound() == null || isJavaLangObject(wildcard.getExtendsBound())) {\n          // This is <?>, unless there's a super bound, in which case it is <? super Foo> and\n          // is erased.\n          return (wildcard.getSuperBound() != null);\n        }\n      }\n      return true;\n    }\n\n    private static boolean isJavaLangObject(TypeMirror type) {\n      if (type.getKind() != TypeKind.DECLARED) {\n        return false;\n      }\n      TypeElement typeElement = asTypeElement(type);\n      return typeElement.getQualifiedName().contentEquals(\"java.lang.Object\");\n    }\n  }\n\n  private MoreTypes() {}\n}\n"
  },
  {
    "path": "common/src/main/java/com/google/auto/common/Overrides.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport static java.util.Objects.requireNonNull;\nimport static java.util.stream.Collectors.toList;\n\nimport com.google.common.base.Preconditions;\nimport com.google.common.base.Verify;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.Lists;\nimport com.google.common.collect.Maps;\nimport java.util.LinkedHashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ElementKind;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.Modifier;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.TypeParameterElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.ArrayType;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.ExecutableType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.type.TypeVariable;\nimport javax.lang.model.util.ElementFilter;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.SimpleTypeVisitor8;\nimport javax.lang.model.util.Types;\nimport org.jspecify.annotations.Nullable;\n\n/**\n * Determines if one method overrides another. This class defines two ways of doing that: {@code\n * NativeOverrides} uses the method {@link Elements#overrides(ExecutableElement, ExecutableElement,\n * TypeElement)} while {@code ExplicitOverrides} reimplements that method in a way that is more\n * consistent between compilers, in particular between javac and ecj (the Eclipse compiler).\n *\n * @see <a href=\"https://github.com/google/auto/issues/372\">AutoValue issue about Eclipse</a>\n * @author emcmanus@google.com (Éamonn McManus)\n */\nabstract class Overrides {\n  abstract boolean overrides(\n      ExecutableElement overrider, ExecutableElement overridden, TypeElement in);\n\n  static class NativeOverrides extends Overrides {\n    private final Elements elementUtils;\n\n    NativeOverrides(Elements elementUtils) {\n      this.elementUtils = elementUtils;\n    }\n\n    @Override\n    boolean overrides(ExecutableElement overrider, ExecutableElement overridden, TypeElement in) {\n      return elementUtils.overrides(overrider, overridden, in);\n    }\n  }\n\n  static class ExplicitOverrides extends Overrides {\n    private final Types typeUtils;\n\n    ExplicitOverrides(Types typeUtils) {\n      this.typeUtils = typeUtils;\n    }\n\n    @Override\n    public boolean overrides(\n        ExecutableElement overrider, ExecutableElement overridden, TypeElement in) {\n      if (!overrider.getSimpleName().equals(overridden.getSimpleName())) {\n        // They must have the same name.\n        return false;\n      }\n      // We should just be able to write overrider.equals(overridden) here, but that runs afoul\n      // of a problem with Eclipse. If for example you look at the method Stream<E> stream() in\n      // Collection<E>, as obtained by collectionTypeElement.getEnclosedElements(), it will not\n      // compare equal to the method Stream<E> stream() as obtained by\n      // elementUtils.getAllMembers(listTypeElement), even though List<E> inherits the method\n      // from Collection<E>. The reason is that, in ecj, getAllMembers does type substitution,\n      // so the return type of stream() is Stream<E'>, where E' is the E from List<E> rather than\n      // the one from Collection<E>. Instead we compare the enclosing element, which will be\n      // Collection<E> no matter how we got the method. If two methods are in the same type\n      // then it's impossible for one to override the other, regardless of whether they are the\n      // same method.\n      if (overrider.getEnclosingElement().equals(overridden.getEnclosingElement())) {\n        return false;\n      }\n      if (overridden.getModifiers().contains(Modifier.STATIC)) {\n        // Static methods can't be overridden (though they can be hidden by other static methods).\n        return false;\n      }\n      if (overrider.getParameters().size() != overridden.getParameters().size()) {\n        // One method can't override another if they have a different number of parameters.\n        // Varargs `Foo...` appears as `Foo[]` here; there is a separate\n        // ExecutableElement.isVarArgs() method to tell whether a method is varargs, but that has no\n        // effect on override logic.\n        // The check here isn't strictly needed but avoids unnecessary work.\n        return false;\n      }\n      Visibility overriddenVisibility = Visibility.ofElement(overridden);\n      Visibility overriderVisibility = Visibility.ofElement(overrider);\n      if (overriddenVisibility.equals(Visibility.PRIVATE)\n          || overriderVisibility.compareTo(overriddenVisibility) < 0) {\n        // Private methods can't be overridden, and methods can't be overridden by less-visible\n        // methods. The latter condition is enforced by the compiler so in theory we might report\n        // an \"incorrect\" result here for code that javac would not have allowed.\n        return false;\n      }\n      if (!isSubsignature(overrider, overridden, in)) {\n        return false;\n      }\n      if (!MoreElements.methodVisibleFromPackage(overridden, MoreElements.getPackage(overrider))) {\n        // If the overridden method is a package-private method in a different package then it\n        // can't be overridden.\n        return false;\n      }\n      if (!MoreElements.isType(overridden.getEnclosingElement())) {\n        return false;\n        // We don't know how this could happen but we avoid blowing up if it does.\n      }\n      TypeElement overriddenType = MoreElements.asType(overridden.getEnclosingElement());\n      // We erase the types before checking subtypes, because the TypeMirror we get for List<E> is\n      // not a subtype of the one we get for Collection<E> since the two E instances are not the\n      // same. For the purposes of overriding, type parameters in the containing type should not\n      // matter because if the code compiles at all then they must be consistent.\n      if (!typeUtils.isSubtype(\n          typeUtils.erasure(in.asType()), typeUtils.erasure(overriddenType.asType()))) {\n        return false;\n      }\n      if (in.getKind().isClass()) {\n        // Method mC in or inherited by class C (JLS 8.4.8.1)...\n        if (overriddenType.getKind().isClass()) {\n          // ...overrides from C another method mA declared in class A. The only condition we\n          // haven't checked is that C does not inherit mA. Ideally we could just write this:\n          //    return !elementUtils.getAllMembers(in).contains(overridden);\n          // But that doesn't work in Eclipse. For example, getAllMembers(AbstractList)\n          // contains List.isEmpty() where you might reasonably expect it to contain\n          // AbstractCollection.isEmpty(). So we need to visit superclasses until we reach\n          // one that declares the same method, and check that we haven't reached mA. We compare\n          // the enclosing elements rather than the methods themselves for the reason described\n          // at the start of the method.\n          ExecutableElement inherited = methodFromSuperclasses(in, overridden);\n          return inherited != null\n              && !overridden.getEnclosingElement().equals(inherited.getEnclosingElement());\n        } else if (overriddenType.getKind().isInterface()) {\n          // ...overrides from C another method mI declared in interface I. We've already checked\n          // the conditions (assuming that the only alternative to mI being abstract or default is\n          // mI being static, which we eliminated above). However, it appears that the logic here\n          // is necessary in order to be compatible with javac's `overrides` method. An inherited\n          // abstract method does not override another method. (But, if it is not inherited,\n          // it does, including if `in` inherits a concrete method of the same name from its\n          // superclass.) Here again we can use getAllMembers with javac but not with ecj. javac\n          // says that getAllMembers(AbstractList) contains both AbstractCollection.size() and\n          // List.size(), but ecj doesn't have the latter. The spec is not particularly clear so\n          // either seems justifiable. So we need to look up the interface path that goes from `in`\n          // to `overriddenType` (or the several paths if there are several) and apply similar logic\n          // to methodFromSuperclasses above.\n          if (overrider.getModifiers().contains(Modifier.ABSTRACT)) {\n            ExecutableElement inherited = methodFromSuperinterfaces(in, overridden);\n            return inherited != null\n                && !overridden.getEnclosingElement().equals(inherited.getEnclosingElement());\n          } else {\n            return true;\n          }\n        } else {\n          // We don't know what this is so say no.\n          return false;\n        }\n      } else {\n        // Method mI in or inherited by interface I (JLS 9.4.1.1). We've already checked everything,\n        // except that `overrider` must also be in a subinterface of `overridden`.\n        // If this is not an interface then we don't know what it is so we say no.\n        TypeElement overriderType = MoreElements.asType(overrider.getEnclosingElement());\n        return in.getKind().isInterface()\n            && typeUtils.isSubtype(\n                typeUtils.erasure(overriderType.asType()),\n                typeUtils.erasure(overriddenType.asType()));\n      }\n    }\n\n    private boolean isSubsignature(\n        ExecutableElement overrider, ExecutableElement overridden, TypeElement in) {\n      DeclaredType inType = MoreTypes.asDeclared(in.asType());\n      try {\n        ExecutableType overriderExecutable =\n            MoreTypes.asExecutable(typeUtils.asMemberOf(inType, overrider));\n        ExecutableType overriddenExecutable =\n            MoreTypes.asExecutable(typeUtils.asMemberOf(inType, overridden));\n        return typeUtils.isSubsignature(overriderExecutable, overriddenExecutable);\n      } catch (IllegalArgumentException e) {\n        // This might mean that at least one of the methods is not in fact declared in or inherited\n        // by `in` (in which case we should indeed return false); or it might mean that we are\n        // tickling an Eclipse bug such as https://bugs.eclipse.org/bugs/show_bug.cgi?id=499026\n        // (in which case we fall back on explicit code to find the parameters).\n        int nParams = overrider.getParameters().size();\n        if (overridden.getParameters().size() != nParams) {\n          return false;\n        }\n        List<TypeMirror> overriderParams = erasedParameterTypes(overrider, in);\n        List<TypeMirror> overriddenParams = erasedParameterTypes(overridden, in);\n        if (overriderParams == null || overriddenParams == null) {\n          // This probably means that one or other of the methods is not in `in`.\n          return false;\n        }\n        for (int i = 0; i < nParams; i++) {\n          if (!typeUtils.isSameType(overriderParams.get(i), overriddenParams.get(i))) {\n            // If the erasures of the parameters don't correspond, return false. We erase so we\n            // don't get any confusion about different type variables not comparing equal.\n            return false;\n          }\n        }\n        return true;\n      }\n    }\n\n    /**\n     * Returns the list of erased parameter types of the given method as they appear in the given\n     * type. For example, if the method is {@code add(E)} from {@code List<E>} and we ask how it\n     * appears in {@code class NumberList implements List<Number>}, the answer will be {@code\n     * Number}. That will also be the answer for {@code class NumberList<E extends Number>\n     * implements List<E>}. The parameter types are erased since the purpose of this method is to\n     * determine whether two methods are candidates for one to override the other.\n     */\n    @Nullable ImmutableList<TypeMirror> erasedParameterTypes(\n        ExecutableElement method, TypeElement in) {\n      if (method.getParameters().isEmpty()) {\n        return ImmutableList.of();\n      }\n      return new TypeSubstVisitor().erasedParameterTypes(method, in);\n    }\n\n    /**\n     * Visitor that replaces type variables with their values in the types it sees. If we know that\n     * {@code E} is {@code String}, then we can return {@code String} for {@code E}, {@code\n     * List<String>} for {@code List<E>}, {@code String[]} for {@code E[]}, etc. We don't have to\n     * cover all types here because (1) the type is going to end up being erased, and (2) wildcards\n     * can't appear in direct supertypes. So for example it is illegal to write {@code class MyList\n     * implements List<? extends Number>}. It's legal to write {@code class MyList implements\n     * List<Set<? extends Number>>} but that doesn't matter because the {@code E} of the {@code\n     * List} is going to be erased to raw {@code Set}.\n     */\n    private class TypeSubstVisitor extends SimpleTypeVisitor8<TypeMirror, Void> {\n      /**\n       * The bindings of type variables. We can put them all in one map because E in {@code List<E>}\n       * is not the same as E in {@code Collection<E>}. As we ascend the type hierarchy we'll add\n       * mappings for all the variables we see. We could equivalently create a new map for each type\n       * we visit, but this is slightly simpler and probably about as performant.\n       */\n      private final Map<TypeParameterElement, TypeMirror> typeBindings = Maps.newLinkedHashMap();\n\n      /**\n       * Type elements that we are currently visiting. This helps us stay out of trouble when\n       * looking at something like {@code Enum<E extends Enum<E>>}. At the second {@code Enum} we\n       * will just return raw {@code Enum}.\n       */\n      private final Set<TypeElement> visitingTypes = new LinkedHashSet<>();\n\n      @Nullable ImmutableList<TypeMirror> erasedParameterTypes(\n          ExecutableElement method, TypeElement in) {\n        if (method.getEnclosingElement().equals(in)) {\n          ImmutableList.Builder<TypeMirror> params = ImmutableList.builder();\n          for (VariableElement param : method.getParameters()) {\n            params.add(typeUtils.erasure(visit(param.asType())));\n          }\n          return params.build();\n        }\n        // Make a list of supertypes we are going to visit recursively: the superclass, if there\n        // is one, plus the superinterfaces.\n        List<TypeMirror> supers = Lists.newArrayList();\n        if (in.getSuperclass().getKind() == TypeKind.DECLARED) {\n          supers.add(in.getSuperclass());\n        }\n        supers.addAll(in.getInterfaces());\n        for (TypeMirror supertype : supers) {\n          DeclaredType declared = MoreTypes.asDeclared(supertype);\n          TypeElement element = MoreElements.asType(declared.asElement());\n          List<? extends TypeMirror> actuals = declared.getTypeArguments();\n          List<? extends TypeParameterElement> formals = element.getTypeParameters();\n          if (actuals.isEmpty()) {\n            // Either the formal type arguments are also empty or `declared` is raw.\n            actuals = formals.stream().map(t -> t.getBounds().get(0)).collect(toList());\n          }\n          Verify.verify(actuals.size() == formals.size());\n          for (int i = 0; i < actuals.size(); i++) {\n            typeBindings.put(formals.get(i), actuals.get(i));\n          }\n          ImmutableList<TypeMirror> params = erasedParameterTypes(method, element);\n          if (params != null) {\n            return params;\n          }\n        }\n        return null;\n      }\n\n      @Override\n      protected TypeMirror defaultAction(TypeMirror e, Void p) {\n        return e;\n      }\n\n      @Override\n      public TypeMirror visitTypeVariable(TypeVariable t, Void p) {\n        Element element = t.asElement();\n        if (element.getKind() == ElementKind.TYPE_PARAMETER) {\n          TypeParameterElement e = (TypeParameterElement) element;\n          if (typeBindings.containsKey(e)) {\n            return visit(typeBindings.get(e));\n          }\n        }\n        // We erase the upper bound to avoid infinite recursion. We can get away with erasure for\n        // the reasons described above.\n        return visit(typeUtils.erasure(t.getUpperBound()));\n      }\n\n      @Override\n      public TypeMirror visitDeclared(DeclaredType t, Void p) {\n        if (t.getTypeArguments().isEmpty()) {\n          return t;\n        }\n        TypeElement typeElement = asTypeElement(t);\n        if (!visitingTypes.add(typeElement)) {\n          return typeUtils.erasure(t);\n        }\n        List<TypeMirror> newArgs = Lists.newArrayList();\n        for (TypeMirror arg : t.getTypeArguments()) {\n          newArgs.add(visit(arg));\n        }\n        TypeMirror result =\n            typeUtils.getDeclaredType(asTypeElement(t), newArgs.toArray(new TypeMirror[0]));\n        visitingTypes.remove(typeElement);\n        return result;\n      }\n\n      @Override\n      public TypeMirror visitArray(ArrayType t, Void p) {\n        return typeUtils.getArrayType(visit(t.getComponentType()));\n      }\n    }\n\n    /**\n     * Returns the given method as it appears in the given type. This is the method itself, or the\n     * nearest override in a superclass of the given type, or null if the method is not found in the\n     * given type or any of its superclasses.\n     */\n    @Nullable ExecutableElement methodFromSuperclasses(TypeElement in, ExecutableElement method) {\n      for (TypeElement t = in; t != null; t = superclass(t)) {\n        ExecutableElement tMethod = methodInType(t, method);\n        if (tMethod != null) {\n          return tMethod;\n        }\n      }\n      return null;\n    }\n\n    /**\n     * Returns the given interface method as it appears in the given type. This is the method\n     * itself, or the nearest override in a superinterface of the given type, or null if the method\n     * is not found in the given type or any of its transitive superinterfaces.\n     */\n    @Nullable ExecutableElement methodFromSuperinterfaces(\n        TypeElement in, ExecutableElement method) {\n      TypeElement methodContainer = MoreElements.asType(method.getEnclosingElement());\n      Preconditions.checkArgument(methodContainer.getKind().isInterface());\n      TypeMirror methodContainerType = typeUtils.erasure(methodContainer.asType());\n      ImmutableList<TypeElement> types = ImmutableList.of(in);\n      // On the first pass through this loop, `types` is the type we're starting from,\n      // which might be a class or an interface. On later passes it is a list of direct\n      // superinterfaces we saw in the previous pass, but only the ones that were assignable\n      // to the interface that `method` appears in.\n      while (!types.isEmpty()) {\n        ImmutableList.Builder<TypeElement> newTypes = ImmutableList.builder();\n        for (TypeElement t : types) {\n          TypeMirror candidateType = typeUtils.erasure(t.asType());\n          if (typeUtils.isAssignable(candidateType, methodContainerType)) {\n            ExecutableElement tMethod = methodInType(t, method);\n            if (tMethod != null) {\n              return tMethod;\n            }\n            newTypes.addAll(superinterfaces(t));\n          }\n          if (t.getKind().isClass()) {\n            TypeElement sup = superclass(t);\n            if (sup != null) {\n              newTypes.add(sup);\n            }\n          }\n        }\n        types = newTypes.build();\n      }\n      return null;\n    }\n\n    /**\n     * Returns the method from within the given type that has the same erased signature as the given\n     * method, or null if there is no such method.\n     */\n    private @Nullable ExecutableElement methodInType(TypeElement type, ExecutableElement method) {\n      int nParams = method.getParameters().size();\n      List<TypeMirror> params = erasedParameterTypes(method, type);\n      if (params == null) {\n        return null;\n      }\n      methods:\n      for (ExecutableElement tMethod : ElementFilter.methodsIn(type.getEnclosedElements())) {\n        if (tMethod.getSimpleName().equals(method.getSimpleName())\n            && tMethod.getParameters().size() == nParams) {\n          for (int i = 0; i < nParams; i++) {\n            TypeMirror tParamType = typeUtils.erasure(tMethod.getParameters().get(i).asType());\n            if (!typeUtils.isSameType(params.get(i), tParamType)) {\n              continue methods;\n            }\n          }\n          return tMethod;\n        }\n      }\n      return null;\n    }\n\n    private @Nullable TypeElement superclass(TypeElement type) {\n      TypeMirror sup = type.getSuperclass();\n      if (sup.getKind() == TypeKind.DECLARED) {\n        // asElement returns non-null for DECLARED types.\n        return MoreElements.asType(requireNonNull(typeUtils.asElement(sup)));\n      } else {\n        return null;\n      }\n    }\n\n    private ImmutableList<TypeElement> superinterfaces(TypeElement type) {\n      ImmutableList.Builder<TypeElement> types = ImmutableList.builder();\n      for (TypeMirror sup : type.getInterfaces()) {\n        /*\n         * All interfaces implemented/extended are DECLARED types, for which asElement returns\n         * non-null.\n         */\n        types.add(MoreElements.asType(requireNonNull(typeUtils.asElement(sup))));\n      }\n      return types.build();\n    }\n\n    private TypeElement asTypeElement(TypeMirror typeMirror) {\n      DeclaredType declaredType = MoreTypes.asDeclared(typeMirror);\n      Element element = declaredType.asElement();\n      return MoreElements.asType(element);\n    }\n  }\n}\n"
  },
  {
    "path": "common/src/main/java/com/google/auto/common/SimpleAnnotationMirror.java",
    "content": "/*\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.auto.common;\n\nimport static com.google.common.base.Preconditions.checkArgument;\nimport static com.google.common.collect.ImmutableMap.toImmutableMap;\nimport static java.util.Objects.requireNonNull;\nimport static javax.lang.model.util.ElementFilter.methodsIn;\n\nimport com.google.common.base.Joiner;\nimport com.google.common.collect.ImmutableMap;\nimport java.util.ArrayList;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.ElementKind;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.DeclaredType;\nimport org.jspecify.annotations.Nullable;\n\n/**\n * A simple implementation of the {@link AnnotationMirror} interface.\n *\n * <p>This type implements {@link #equals(Object)} and {@link #hashCode()} using {@link\n * AnnotationMirrors#equivalence} in accordance with the {@link AnnotationMirror} spec. Some {@link\n * AnnotationMirror}s, however, do not correctly implement equals, you should always compare them\n * using {@link AnnotationMirrors#equivalence} anyway.\n */\npublic final class SimpleAnnotationMirror implements AnnotationMirror {\n  private final TypeElement annotationType;\n  private final ImmutableMap<String, ? extends AnnotationValue> namedValues;\n  private final ImmutableMap<ExecutableElement, ? extends AnnotationValue> elementValues;\n\n  private SimpleAnnotationMirror(\n      TypeElement annotationType, Map<String, ? extends AnnotationValue> namedValues) {\n    checkArgument(\n        annotationType.getKind().equals(ElementKind.ANNOTATION_TYPE),\n        \"annotationType must be an annotation: %s\",\n        annotationType);\n    Map<String, AnnotationValue> values = new LinkedHashMap<>();\n    Map<String, AnnotationValue> unusedValues = new LinkedHashMap<>(namedValues);\n    List<String> missingMembers = new ArrayList<>();\n    for (ExecutableElement method : methodsIn(annotationType.getEnclosedElements())) {\n      String memberName = method.getSimpleName().toString();\n      if (unusedValues.containsKey(memberName)) {\n        values.put(memberName, unusedValues.remove(memberName));\n      } else if (method.getDefaultValue() != null) {\n        values.put(memberName, method.getDefaultValue());\n      } else {\n        missingMembers.add(memberName);\n      }\n    }\n\n    checkArgument(\n        unusedValues.isEmpty(),\n        \"namedValues has entries for members that are not in %s: %s\",\n        annotationType,\n        unusedValues);\n    checkArgument(\n        missingMembers.isEmpty(), \"namedValues is missing entries for: %s\", missingMembers);\n\n    this.annotationType = annotationType;\n    this.namedValues = ImmutableMap.copyOf(namedValues);\n    this.elementValues =\n        methodsIn(annotationType.getEnclosedElements()).stream()\n            .collect(\n                toImmutableMap(\n                    e -> e,\n                    // requireNonNull is safe because we inserted into `values` for all methods.\n                    e -> requireNonNull(values.get(e.getSimpleName().toString()))));\n  }\n\n  /**\n   * An object representing an {@linkplain ElementKind#ANNOTATION_TYPE annotation} instance. If\n   * {@code annotationType} has any annotation members, they must have default values.\n   */\n  public static AnnotationMirror of(TypeElement annotationType) {\n    return of(annotationType, ImmutableMap.of());\n  }\n\n  /**\n   * An object representing an {@linkplain ElementKind#ANNOTATION_TYPE annotation} instance. If\n   * {@code annotationType} has any annotation members, they must either be present in {@code\n   * namedValues} or have default values.\n   */\n  public static AnnotationMirror of(\n      TypeElement annotationType, Map<String, ? extends AnnotationValue> namedValues) {\n    return new SimpleAnnotationMirror(annotationType, namedValues);\n  }\n\n  @Override\n  public DeclaredType getAnnotationType() {\n    return MoreTypes.asDeclared(annotationType.asType());\n  }\n\n  @Override\n  public Map<ExecutableElement, ? extends AnnotationValue> getElementValues() {\n    return elementValues;\n  }\n\n  @Override\n  public String toString() {\n    StringBuilder builder = new StringBuilder(\"@\").append(annotationType.getQualifiedName());\n    if (!namedValues.isEmpty()) {\n      builder\n          .append('(')\n          .append(Joiner.on(\", \").withKeyValueSeparator(\" = \").join(namedValues))\n          .append(')');\n    }\n    return builder.toString();\n  }\n\n  @Override\n  public boolean equals(@Nullable Object other) {\n    return other instanceof AnnotationMirror\n        && AnnotationMirrors.equivalence().equivalent(this, (AnnotationMirror) other);\n  }\n\n  @Override\n  public int hashCode() {\n    return AnnotationMirrors.equivalence().hash(this);\n  }\n}\n"
  },
  {
    "path": "common/src/main/java/com/google/auto/common/SimpleTypeAnnotationValue.java",
    "content": "/*\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.auto.common;\n\nimport static com.google.common.base.Preconditions.checkArgument;\nimport static javax.lang.model.type.TypeKind.ARRAY;\nimport static javax.lang.model.type.TypeKind.DECLARED;\n\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.AnnotationValueVisitor;\nimport javax.lang.model.type.TypeMirror;\n\n/**\n * A simple implementation of the {@link AnnotationValue} interface for a class literal, e.g. an\n * annotation member of type {@code Class<?>} or {@code Class<? extends Foo>}.\n */\npublic final class SimpleTypeAnnotationValue implements AnnotationValue {\n  private final TypeMirror value;\n\n  private SimpleTypeAnnotationValue(TypeMirror value) {\n    checkArgument(\n        value.getKind().isPrimitive()\n            || value.getKind().equals(DECLARED)\n            || value.getKind().equals(ARRAY),\n        \"value must be a primitive, array, or declared type, but was %s (%s)\",\n        value.getKind(),\n        value);\n    if (value.getKind().equals(DECLARED)) {\n      checkArgument(\n          MoreTypes.asDeclared(value).getTypeArguments().isEmpty(),\n          \"value must not be a parameterized type: %s\",\n          value);\n    }\n    this.value = value;\n  }\n\n  /**\n   * An object representing an annotation value instance.\n   *\n   * @param value a primitive, array, or non-parameterized declared type\n   */\n  public static AnnotationValue of(TypeMirror value) {\n    return new SimpleTypeAnnotationValue(value);\n  }\n\n  @Override\n  public TypeMirror getValue() {\n    return value;\n  }\n\n  @Override\n  public String toString() {\n    return value + \".class\";\n  }\n\n  @Override\n  public <R, P> R accept(AnnotationValueVisitor<R, P> visitor, P parameter) {\n    return visitor.visitType(getValue(), parameter);\n  }\n}\n"
  },
  {
    "path": "common/src/main/java/com/google/auto/common/SuperficialValidation.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.stream.StreamSupport;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.AnnotationValueVisitor;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ElementVisitor;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.PackageElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.TypeParameterElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.ArrayType;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.ErrorType;\nimport javax.lang.model.type.ExecutableType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.type.TypeVisitor;\nimport javax.lang.model.type.WildcardType;\nimport javax.lang.model.util.AbstractElementVisitor8;\nimport javax.lang.model.util.SimpleAnnotationValueVisitor8;\nimport javax.lang.model.util.SimpleTypeVisitor8;\n\n/**\n * A utility class that traverses {@link Element} instances and ensures that all type information is\n * present and resolvable.\n *\n * @author Gregory Kick\n */\npublic final class SuperficialValidation {\n  /**\n   * Returns true if all of the given elements return true from {@link #validateElement(Element)}.\n   */\n  public static boolean validateElements(Iterable<? extends Element> elements) {\n    return StreamSupport.stream(elements.spliterator(), false)\n        .allMatch(SuperficialValidation::validateElement);\n  }\n\n  private static final ElementVisitor<Boolean, Void> ELEMENT_VALIDATING_VISITOR =\n      new AbstractElementVisitor8<Boolean, Void>() {\n        @Override\n        public Boolean visitPackage(PackageElement e, Void p) {\n          // don't validate enclosed elements because it will return types in the package\n          return validateAnnotations(e.getAnnotationMirrors());\n        }\n\n        @Override\n        public Boolean visitType(TypeElement e, Void p) {\n          return isValidBaseElement(e)\n              && validateElements(e.getTypeParameters())\n              && validateTypes(e.getInterfaces())\n              && validateType(e.getSuperclass());\n        }\n\n        @Override\n        public Boolean visitVariable(VariableElement e, Void p) {\n          return isValidBaseElement(e);\n        }\n\n        @Override\n        public Boolean visitExecutable(ExecutableElement e, Void p) {\n          AnnotationValue defaultValue = e.getDefaultValue();\n          return isValidBaseElement(e)\n              && (defaultValue == null || validateAnnotationValue(defaultValue, e.getReturnType()))\n              && validateType(e.getReturnType())\n              && validateTypes(e.getThrownTypes())\n              && validateElements(e.getTypeParameters())\n              && validateElements(e.getParameters());\n        }\n\n        @Override\n        public Boolean visitTypeParameter(TypeParameterElement e, Void p) {\n          return isValidBaseElement(e) && validateTypes(e.getBounds());\n        }\n\n        @Override\n        public Boolean visitUnknown(Element e, Void p) {\n          // just assume that unknown elements are OK\n          return true;\n        }\n      };\n\n  /**\n   * Returns true if all types referenced by the given element are defined. The exact meaning of\n   * this depends on the kind of element. For packages, it means that all annotations on the package\n   * are fully defined. For other element kinds, it means that types referenced by the element,\n   * anything it contains, and any of its annotations element are all defined.\n   */\n  public static boolean validateElement(Element element) {\n    return element.accept(ELEMENT_VALIDATING_VISITOR, null);\n  }\n\n  private static boolean isValidBaseElement(Element e) {\n    return validateType(e.asType())\n        && validateAnnotations(e.getAnnotationMirrors())\n        && validateElements(e.getEnclosedElements());\n  }\n\n  private static boolean validateTypes(Iterable<? extends TypeMirror> types) {\n    for (TypeMirror type : types) {\n      if (!validateType(type)) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  /*\n   * This visitor does not test type variables specifically, but it seems that that is not actually\n   * an issue.  Javac turns the whole type parameter into an error type if it can't figure out the\n   * bounds.\n   */\n  private static final TypeVisitor<Boolean, Void> TYPE_VALIDATING_VISITOR =\n      new SimpleTypeVisitor8<Boolean, Void>() {\n        @Override\n        protected Boolean defaultAction(TypeMirror t, Void p) {\n          return true;\n        }\n\n        @Override\n        public Boolean visitArray(ArrayType t, Void p) {\n          return validateType(t.getComponentType());\n        }\n\n        @Override\n        public Boolean visitDeclared(DeclaredType t, Void p) {\n          return validateTypes(t.getTypeArguments());\n        }\n\n        @Override\n        public Boolean visitError(ErrorType t, Void p) {\n          return false;\n        }\n\n        @Override\n        public Boolean visitUnknown(TypeMirror t, Void p) {\n          // just make the default choice for unknown types\n          return defaultAction(t, p);\n        }\n\n        @Override\n        public Boolean visitWildcard(WildcardType t, Void p) {\n          TypeMirror extendsBound = t.getExtendsBound();\n          TypeMirror superBound = t.getSuperBound();\n          return (extendsBound == null || validateType(extendsBound))\n              && (superBound == null || validateType(superBound));\n        }\n\n        @Override\n        public Boolean visitExecutable(ExecutableType t, Void p) {\n          return validateTypes(t.getParameterTypes())\n              && validateType(t.getReturnType())\n              && validateTypes(t.getThrownTypes())\n              && validateTypes(t.getTypeVariables());\n        }\n      };\n\n  /**\n   * Returns true if the given type is fully defined. This means that the type itself is defined, as\n   * are any types it references, such as any type arguments or type bounds. For an {@link\n   * ExecutableType}, the parameter and return types must be fully defined, as must types declared\n   * in a {@code throws} clause or in the bounds of any type parameters.\n   */\n  public static boolean validateType(TypeMirror type) {\n    return type.accept(TYPE_VALIDATING_VISITOR, null);\n  }\n\n  private static boolean validateAnnotations(\n      Iterable<? extends AnnotationMirror> annotationMirrors) {\n    for (AnnotationMirror annotationMirror : annotationMirrors) {\n      if (!validateAnnotation(annotationMirror)) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  private static boolean validateAnnotation(AnnotationMirror annotationMirror) {\n    return validateType(annotationMirror.getAnnotationType())\n        && validateAnnotationValues(annotationMirror.getElementValues());\n  }\n\n  private static boolean validateAnnotationValues(\n      Map<? extends ExecutableElement, ? extends AnnotationValue> valueMap) {\n    return valueMap.entrySet().stream()\n        .allMatch(\n            valueEntry -> {\n              TypeMirror expectedType = valueEntry.getKey().getReturnType();\n              return validateAnnotationValue(valueEntry.getValue(), expectedType);\n            });\n  }\n\n  private static final AnnotationValueVisitor<Boolean, TypeMirror> VALUE_VALIDATING_VISITOR =\n      new SimpleAnnotationValueVisitor8<Boolean, TypeMirror>() {\n        @Override\n        protected Boolean defaultAction(Object o, TypeMirror expectedType) {\n          return MoreTypes.isTypeOf(o.getClass(), expectedType);\n        }\n\n        @Override\n        public Boolean visitUnknown(AnnotationValue av, TypeMirror expectedType) {\n          // just take the default action for the unknown\n          return defaultAction(av, expectedType);\n        }\n\n        @Override\n        public Boolean visitAnnotation(AnnotationMirror a, TypeMirror expectedType) {\n          return MoreTypes.equivalence().equivalent(a.getAnnotationType(), expectedType)\n              && validateAnnotation(a);\n        }\n\n        @Override\n        public Boolean visitArray(List<? extends AnnotationValue> values, TypeMirror expectedType) {\n          if (!expectedType.getKind().equals(TypeKind.ARRAY)) {\n            return false;\n          }\n          TypeMirror componentType = MoreTypes.asArray(expectedType).getComponentType();\n          return values.stream().allMatch(value -> value.accept(this, componentType));\n        }\n\n        @Override\n        public Boolean visitEnumConstant(VariableElement enumConstant, TypeMirror expectedType) {\n          return MoreTypes.equivalence().equivalent(enumConstant.asType(), expectedType)\n              && validateElement(enumConstant);\n        }\n\n        @Override\n        public Boolean visitType(TypeMirror type, TypeMirror ignored) {\n          // We could check assignability here, but would require a Types instance. Since this\n          // isn't really the sort of thing that shows up in a bad AST from upstream compilation\n          // we ignore the expected type and just validate the type.  It might be wrong, but\n          // it's valid.\n          return validateType(type);\n        }\n\n        @Override\n        public Boolean visitBoolean(boolean b, TypeMirror expectedType) {\n          return MoreTypes.isTypeOf(Boolean.TYPE, expectedType);\n        }\n\n        @Override\n        public Boolean visitByte(byte b, TypeMirror expectedType) {\n          return MoreTypes.isTypeOf(Byte.TYPE, expectedType);\n        }\n\n        @Override\n        public Boolean visitChar(char c, TypeMirror expectedType) {\n          return MoreTypes.isTypeOf(Character.TYPE, expectedType);\n        }\n\n        @Override\n        public Boolean visitDouble(double d, TypeMirror expectedType) {\n          return MoreTypes.isTypeOf(Double.TYPE, expectedType);\n        }\n\n        @Override\n        public Boolean visitFloat(float f, TypeMirror expectedType) {\n          return MoreTypes.isTypeOf(Float.TYPE, expectedType);\n        }\n\n        @Override\n        public Boolean visitInt(int i, TypeMirror expectedType) {\n          return MoreTypes.isTypeOf(Integer.TYPE, expectedType);\n        }\n\n        @Override\n        public Boolean visitLong(long l, TypeMirror expectedType) {\n          return MoreTypes.isTypeOf(Long.TYPE, expectedType);\n        }\n\n        @Override\n        public Boolean visitShort(short s, TypeMirror expectedType) {\n          return MoreTypes.isTypeOf(Short.TYPE, expectedType);\n        }\n      };\n\n  private static boolean validateAnnotationValue(\n      AnnotationValue annotationValue, TypeMirror expectedType) {\n    return annotationValue.accept(VALUE_VALIDATING_VISITOR, expectedType);\n  }\n\n  private SuperficialValidation() {}\n}\n"
  },
  {
    "path": "common/src/main/java/com/google/auto/common/Visibility.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport static com.google.common.base.Preconditions.checkNotNull;\nimport static javax.lang.model.element.ElementKind.PACKAGE;\n\nimport com.google.common.base.Enums;\nimport com.google.common.collect.Ordering;\nimport java.util.Set;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ElementKind;\nimport javax.lang.model.element.Modifier;\nimport org.jspecify.annotations.Nullable;\n\n/**\n * Represents the visibility of a given {@link Element}: {@code public}, {@code protected}, {@code\n * private} or default/package-private.\n *\n * <p>The constants for this enum are ordered according by increasing visibility.\n *\n * @author Gregory Kick\n */\npublic enum Visibility {\n  PRIVATE,\n  DEFAULT,\n  PROTECTED,\n  PUBLIC;\n\n  // TODO(ronshapiro): remove this and reference ElementKind.MODULE directly once we start building\n  // with -source 9\n  private static final @Nullable ElementKind MODULE =\n      Enums.getIfPresent(ElementKind.class, \"MODULE\").orNull();\n\n  /**\n   * Returns the visibility of the given {@link Element}. While package and module elements don't\n   * technically have a visibility associated with them, this method returns {@link #PUBLIC} for\n   * them.\n   */\n  public static Visibility ofElement(Element element) {\n    checkNotNull(element);\n    // packages and module don't have modifiers, but they're obviously \"public\"\n    if (element.getKind().equals(PACKAGE) || element.getKind().equals(MODULE)) {\n      return PUBLIC;\n    }\n    Set<Modifier> modifiers = element.getModifiers();\n    if (modifiers.contains(Modifier.PRIVATE)) {\n      return PRIVATE;\n    } else if (modifiers.contains(Modifier.PROTECTED)) {\n      return PROTECTED;\n    } else if (modifiers.contains(Modifier.PUBLIC)) {\n      return PUBLIC;\n    } else {\n      return DEFAULT;\n    }\n  }\n\n  /**\n   * Returns effective visibility of the given element meaning that it takes into account the\n   * visibility of its enclosing elements.\n   */\n  public static Visibility effectiveVisibilityOfElement(Element element) {\n    checkNotNull(element);\n    Visibility effectiveVisibility = PUBLIC;\n    Element currentElement = element;\n    while (currentElement != null) {\n      // NOTE: We don't use Guava's Comparators.min() because that requires Guava 30, which would\n      // make this library unusable in annotation processors using Bazel < 5.0.\n      effectiveVisibility = Ordering.natural().min(effectiveVisibility, ofElement(currentElement));\n      currentElement = currentElement.getEnclosingElement();\n    }\n    return effectiveVisibility;\n  }\n}\n"
  },
  {
    "path": "common/src/main/java/com/google/auto/common/package-info.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n@NullMarked\npackage com.google.auto.common;\n\nimport org.jspecify.annotations.NullMarked;\n"
  },
  {
    "path": "common/src/test/java/com/google/auto/common/AnnotationMirrorsTest.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport static com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.BLAH;\nimport static com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.FOO;\nimport static com.google.common.collect.Iterables.getOnlyElement;\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.testing.compile.CompilationSubject.assertThat;\nimport static org.junit.Assert.fail;\n\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.testing.EquivalenceTester;\nimport com.google.common.truth.Correspondence;\nimport com.google.testing.compile.CompilationRule;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.util.Map;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.SimpleAnnotationValueVisitor6;\nimport org.junit.Before;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/** Tests {@link AnnotationMirrors}. */\n@RunWith(JUnit4.class)\npublic class AnnotationMirrorsTest {\n  @Rule public CompilationRule compilationRule = new CompilationRule();\n\n  private Elements elements;\n\n  @Before\n  public void setUp() {\n    this.elements = compilationRule.getElements();\n  }\n\n  @interface SimpleAnnotation {}\n\n  @SimpleAnnotation\n  static class SimplyAnnotated {}\n\n  @SimpleAnnotation\n  static class AlsoSimplyAnnotated {}\n\n  enum SimpleEnum {\n    BLAH,\n    FOO\n  }\n\n  @interface Outer {\n    SimpleEnum value();\n  }\n\n  @Outer(BLAH)\n  static class TestClassBlah {}\n\n  @Outer(BLAH)\n  static class TestClassBlah2 {}\n\n  @Outer(FOO)\n  static class TestClassFoo {}\n\n  @interface DefaultingOuter {\n    SimpleEnum value() default SimpleEnum.BLAH;\n  }\n\n  @DefaultingOuter\n  static class TestWithDefaultingOuterDefault {}\n\n  @DefaultingOuter(BLAH)\n  static class TestWithDefaultingOuterBlah {}\n\n  @DefaultingOuter(FOO)\n  static class TestWithDefaultingOuterFoo {}\n\n  @interface AnnotatedOuter {\n    DefaultingOuter value();\n  }\n\n  @AnnotatedOuter(@DefaultingOuter)\n  static class TestDefaultNestedAnnotated {}\n\n  @AnnotatedOuter(@DefaultingOuter(BLAH))\n  static class TestBlahNestedAnnotated {}\n\n  @AnnotatedOuter(@DefaultingOuter(FOO))\n  static class TestFooNestedAnnotated {}\n\n  @interface OuterWithValueArray {\n    DefaultingOuter[] value() default {};\n  }\n\n  @OuterWithValueArray\n  static class TestValueArrayWithDefault {}\n\n  @OuterWithValueArray({})\n  static class TestValueArrayWithEmpty {}\n\n  @OuterWithValueArray({@DefaultingOuter})\n  static class TestValueArrayWithOneDefault {}\n\n  @OuterWithValueArray(@DefaultingOuter(BLAH))\n  static class TestValueArrayWithOneBlah {}\n\n  @OuterWithValueArray(@DefaultingOuter(FOO))\n  static class TestValueArrayWithOneFoo {}\n\n  @OuterWithValueArray({@DefaultingOuter(FOO), @DefaultingOuter})\n  class TestValueArrayWithFooAndDefaultBlah {}\n\n  @OuterWithValueArray({@DefaultingOuter(FOO), @DefaultingOuter(BLAH)})\n  class TestValueArrayWithFooBlah {}\n\n  @OuterWithValueArray({@DefaultingOuter(FOO), @DefaultingOuter(BLAH)})\n  class TestValueArrayWithFooBlah2 {} // Different instances than on TestValueArrayWithFooBlah.\n\n  @OuterWithValueArray({@DefaultingOuter(BLAH), @DefaultingOuter(FOO)})\n  class TestValueArrayWithBlahFoo {}\n\n  @Test\n  public void testEquivalences() {\n    EquivalenceTester<AnnotationMirror> tester =\n        EquivalenceTester.of(AnnotationMirrors.equivalence());\n\n    tester.addEquivalenceGroup(\n        annotationOn(SimplyAnnotated.class), annotationOn(AlsoSimplyAnnotated.class));\n\n    tester.addEquivalenceGroup(\n        annotationOn(TestClassBlah.class), annotationOn(TestClassBlah2.class));\n\n    tester.addEquivalenceGroup(annotationOn(TestClassFoo.class));\n\n    tester.addEquivalenceGroup(\n        annotationOn(TestWithDefaultingOuterDefault.class),\n        annotationOn(TestWithDefaultingOuterBlah.class));\n\n    tester.addEquivalenceGroup(annotationOn(TestWithDefaultingOuterFoo.class));\n\n    tester.addEquivalenceGroup(\n        annotationOn(TestDefaultNestedAnnotated.class),\n        annotationOn(TestBlahNestedAnnotated.class));\n\n    tester.addEquivalenceGroup(annotationOn(TestFooNestedAnnotated.class));\n\n    tester.addEquivalenceGroup(\n        annotationOn(TestValueArrayWithDefault.class), annotationOn(TestValueArrayWithEmpty.class));\n\n    tester.addEquivalenceGroup(\n        annotationOn(TestValueArrayWithOneDefault.class),\n        annotationOn(TestValueArrayWithOneBlah.class));\n\n    tester.addEquivalenceGroup(annotationOn(TestValueArrayWithOneFoo.class));\n\n    tester.addEquivalenceGroup(\n        annotationOn(TestValueArrayWithFooAndDefaultBlah.class),\n        annotationOn(TestValueArrayWithFooBlah.class),\n        annotationOn(TestValueArrayWithFooBlah2.class));\n\n    tester.addEquivalenceGroup(annotationOn(TestValueArrayWithBlahFoo.class));\n\n    tester.test();\n  }\n\n  @interface Stringy {\n    String value() default \"default\";\n  }\n\n  @Stringy\n  static class StringyUnset {}\n\n  @Stringy(\"foo\")\n  static class StringySet {}\n\n  @Test\n  public void testGetDefaultValuesUnset() {\n    assertThat(annotationOn(StringyUnset.class).getElementValues()).isEmpty();\n    Iterable<AnnotationValue> values =\n        AnnotationMirrors.getAnnotationValuesWithDefaults(annotationOn(StringyUnset.class))\n            .values();\n    String value =\n        getOnlyElement(values)\n            .accept(\n                new SimpleAnnotationValueVisitor6<String, Void>() {\n                  @Override\n                  public String visitString(String value, Void ignored) {\n                    return value;\n                  }\n                },\n                null);\n    assertThat(value).isEqualTo(\"default\");\n  }\n\n  @Test\n  public void testGetDefaultValuesSet() {\n    Iterable<AnnotationValue> values =\n        AnnotationMirrors.getAnnotationValuesWithDefaults(annotationOn(StringySet.class)).values();\n    String value =\n        getOnlyElement(values)\n            .accept(\n                new SimpleAnnotationValueVisitor6<String, Void>() {\n                  @Override\n                  public String visitString(String value, Void ignored) {\n                    return value;\n                  }\n                },\n                null);\n    assertThat(value).isEqualTo(\"foo\");\n  }\n\n  @Test\n  public void testGetValueEntry() {\n    Map.Entry<ExecutableElement, AnnotationValue> elementValue =\n        AnnotationMirrors.getAnnotationElementAndValue(annotationOn(TestClassBlah.class), \"value\");\n    assertThat(elementValue.getKey().getSimpleName().toString()).isEqualTo(\"value\");\n    assertThat(elementValue.getValue().getValue()).isInstanceOf(VariableElement.class);\n    AnnotationValue value =\n        AnnotationMirrors.getAnnotationValue(annotationOn(TestClassBlah.class), \"value\");\n    assertThat(value.getValue()).isInstanceOf(VariableElement.class);\n  }\n\n  @Test\n  public void testGetValueEntryFailure() {\n    try {\n      AnnotationMirrors.getAnnotationValue(annotationOn(TestClassBlah.class), \"a\");\n    } catch (IllegalArgumentException e) {\n      assertThat(e)\n          .hasMessageThat()\n          .isEqualTo(\n              \"@com.google.auto.common.AnnotationMirrorsTest.Outer does not define an element a()\");\n      return;\n    }\n    fail(\"Should have thrown.\");\n  }\n\n  private AnnotationMirror annotationOn(Class<?> clazz) {\n    return getOnlyElement(elements.getTypeElement(clazz.getCanonicalName()).getAnnotationMirrors());\n  }\n\n  @Retention(RetentionPolicy.RUNTIME)\n  private @interface AnnotatingAnnotation {}\n\n  @AnnotatingAnnotation\n  @Retention(RetentionPolicy.RUNTIME)\n  private @interface AnnotatedAnnotation1 {}\n\n  @AnnotatingAnnotation\n  @Retention(RetentionPolicy.RUNTIME)\n  private @interface AnnotatedAnnotation2 {}\n\n  @Retention(RetentionPolicy.RUNTIME)\n  private @interface NotAnnotatedAnnotation {}\n\n  @AnnotatedAnnotation1\n  @NotAnnotatedAnnotation\n  @AnnotatedAnnotation2\n  private static final class AnnotatedClass {}\n\n  @Test\n  public void getAnnotatedAnnotations() {\n    TypeElement element = elements.getTypeElement(AnnotatedClass.class.getCanonicalName());\n\n    // Test Class API\n    getAnnotatedAnnotationsAsserts(\n        AnnotationMirrors.getAnnotatedAnnotations(element, AnnotatingAnnotation.class));\n\n    // Test String API\n    String annotatingAnnotationName = AnnotatingAnnotation.class.getCanonicalName();\n    getAnnotatedAnnotationsAsserts(\n        AnnotationMirrors.getAnnotatedAnnotations(element, annotatingAnnotationName));\n\n    // Test TypeElement API\n    TypeElement annotatingAnnotationElement = elements.getTypeElement(annotatingAnnotationName);\n    getAnnotatedAnnotationsAsserts(\n        AnnotationMirrors.getAnnotatedAnnotations(element, annotatingAnnotationElement));\n  }\n\n  @Test\n  public void toSourceString() {\n    assertThat(AnnotationMirrors.toString(annotationOn(AlsoSimplyAnnotated.class)))\n        .isEqualTo(\"@com.google.auto.common.AnnotationMirrorsTest.SimpleAnnotation\");\n    assertThat(AnnotationMirrors.toString(annotationOn(SimplyAnnotated.class)))\n        .isEqualTo(\"@com.google.auto.common.AnnotationMirrorsTest.SimpleAnnotation\");\n    assertThat(AnnotationMirrors.toString(annotationOn(StringySet.class)))\n        .isEqualTo(\"@com.google.auto.common.AnnotationMirrorsTest.Stringy(\\\"foo\\\")\");\n    assertThat(AnnotationMirrors.toString(annotationOn(StringyUnset.class)))\n        .isEqualTo(\"@com.google.auto.common.AnnotationMirrorsTest.Stringy\");\n    assertThat(AnnotationMirrors.toString(annotationOn(TestBlahNestedAnnotated.class)))\n        .isEqualTo(\n            \"@com.google.auto.common.AnnotationMirrorsTest.AnnotatedOuter(@com.google.auto.common.AnnotationMirrorsTest.DefaultingOuter(com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.BLAH))\");\n    assertThat(AnnotationMirrors.toString(annotationOn(TestClassBlah2.class)))\n        .isEqualTo(\n            \"@com.google.auto.common.AnnotationMirrorsTest.Outer(com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.BLAH)\");\n    assertThat(AnnotationMirrors.toString(annotationOn(TestClassBlah.class)))\n        .isEqualTo(\n            \"@com.google.auto.common.AnnotationMirrorsTest.Outer(com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.BLAH)\");\n    assertThat(AnnotationMirrors.toString(annotationOn(TestClassFoo.class)))\n        .isEqualTo(\n            \"@com.google.auto.common.AnnotationMirrorsTest.Outer(com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.FOO)\");\n    assertThat(AnnotationMirrors.toString(annotationOn(TestDefaultNestedAnnotated.class)))\n        .isEqualTo(\n            \"@com.google.auto.common.AnnotationMirrorsTest.AnnotatedOuter(@com.google.auto.common.AnnotationMirrorsTest.DefaultingOuter)\");\n    assertThat(AnnotationMirrors.toString(annotationOn(TestFooNestedAnnotated.class)))\n        .isEqualTo(\n            \"@com.google.auto.common.AnnotationMirrorsTest.AnnotatedOuter(@com.google.auto.common.AnnotationMirrorsTest.DefaultingOuter(com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.FOO))\");\n    assertThat(AnnotationMirrors.toString(annotationOn(TestValueArrayWithBlahFoo.class)))\n        .isEqualTo(\n            \"@com.google.auto.common.AnnotationMirrorsTest.OuterWithValueArray({@com.google.auto.common.AnnotationMirrorsTest.DefaultingOuter(com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.BLAH),\"\n                + \" @com.google.auto.common.AnnotationMirrorsTest.DefaultingOuter(com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.FOO)})\");\n    assertThat(AnnotationMirrors.toString(annotationOn(TestValueArrayWithDefault.class)))\n        .isEqualTo(\"@com.google.auto.common.AnnotationMirrorsTest.OuterWithValueArray\");\n    assertThat(AnnotationMirrors.toString(annotationOn(TestValueArrayWithEmpty.class)))\n        .isEqualTo(\"@com.google.auto.common.AnnotationMirrorsTest.OuterWithValueArray({})\");\n    assertThat(AnnotationMirrors.toString(annotationOn(TestValueArrayWithFooAndDefaultBlah.class)))\n        .isEqualTo(\n            \"@com.google.auto.common.AnnotationMirrorsTest.OuterWithValueArray({@com.google.auto.common.AnnotationMirrorsTest.DefaultingOuter(com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.FOO),\"\n                + \" @com.google.auto.common.AnnotationMirrorsTest.DefaultingOuter})\");\n    assertThat(AnnotationMirrors.toString(annotationOn(TestValueArrayWithFooBlah2.class)))\n        .isEqualTo(\n            \"@com.google.auto.common.AnnotationMirrorsTest.OuterWithValueArray({@com.google.auto.common.AnnotationMirrorsTest.DefaultingOuter(com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.FOO),\"\n                + \" @com.google.auto.common.AnnotationMirrorsTest.DefaultingOuter(com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.BLAH)})\");\n    assertThat(AnnotationMirrors.toString(annotationOn(TestValueArrayWithFooBlah.class)))\n        .isEqualTo(\n            \"@com.google.auto.common.AnnotationMirrorsTest.OuterWithValueArray({@com.google.auto.common.AnnotationMirrorsTest.DefaultingOuter(com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.FOO),\"\n                + \" @com.google.auto.common.AnnotationMirrorsTest.DefaultingOuter(com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.BLAH)})\");\n    assertThat(AnnotationMirrors.toString(annotationOn(TestValueArrayWithOneBlah.class)))\n        .isEqualTo(\n            \"@com.google.auto.common.AnnotationMirrorsTest.OuterWithValueArray(@com.google.auto.common.AnnotationMirrorsTest.DefaultingOuter(com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.BLAH))\");\n    assertThat(AnnotationMirrors.toString(annotationOn(TestValueArrayWithOneDefault.class)))\n        .isEqualTo(\n            \"@com.google.auto.common.AnnotationMirrorsTest.OuterWithValueArray(@com.google.auto.common.AnnotationMirrorsTest.DefaultingOuter)\");\n    assertThat(AnnotationMirrors.toString(annotationOn(TestValueArrayWithOneFoo.class)))\n        .isEqualTo(\n            \"@com.google.auto.common.AnnotationMirrorsTest.OuterWithValueArray(@com.google.auto.common.AnnotationMirrorsTest.DefaultingOuter(com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.FOO))\");\n    assertThat(AnnotationMirrors.toString(annotationOn(TestWithDefaultingOuterBlah.class)))\n        .isEqualTo(\n            \"@com.google.auto.common.AnnotationMirrorsTest.DefaultingOuter(com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.BLAH)\");\n    assertThat(AnnotationMirrors.toString(annotationOn(TestWithDefaultingOuterDefault.class)))\n        .isEqualTo(\"@com.google.auto.common.AnnotationMirrorsTest.DefaultingOuter\");\n    assertThat(AnnotationMirrors.toString(annotationOn(TestWithDefaultingOuterFoo.class)))\n        .isEqualTo(\n            \"@com.google.auto.common.AnnotationMirrorsTest.DefaultingOuter(com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.FOO)\");\n  }\n\n  private void getAnnotatedAnnotationsAsserts(\n      ImmutableSet<? extends AnnotationMirror> annotatedAnnotations) {\n    assertThat(annotatedAnnotations)\n        .comparingElementsUsing(\n            Correspondence.transforming(\n                (AnnotationMirror a) -> MoreTypes.asTypeElement(a.getAnnotationType()), \"has type\"))\n        .containsExactly(\n            elements.getTypeElement(AnnotatedAnnotation1.class.getCanonicalName()),\n            elements.getTypeElement(AnnotatedAnnotation2.class.getCanonicalName()));\n  }\n}\n"
  },
  {
    "path": "common/src/test/java/com/google/auto/common/AnnotationValuesTest.java",
    "content": "/*\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static com.google.common.truth.Truth.assertThat;\nimport static java.util.stream.Collectors.joining;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.truth.Correspondence;\nimport com.google.testing.compile.CompilationRule;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.Name;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.Types;\nimport org.junit.Before;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/** Tests {@link AnnotationValues}. */\n@RunWith(JUnit4.class)\npublic final class AnnotationValuesTest {\n\n  private @interface InsideAnnotation {\n    int value();\n  }\n\n  private static class GenericClass<T> {}\n\n  private static class InsideClassA {}\n\n  private static class InsideClassB {}\n\n  private @interface MultiValueAnnotation {\n    Class<InsideClassA> classValue();\n\n    Class<?>[] classValues();\n\n    Class<?> genericClassValue();\n\n    InsideAnnotation insideAnnotationValue();\n\n    InsideAnnotation[] insideAnnotationValues();\n\n    String stringValue();\n\n    String[] stringValues();\n\n    Foo enumValue();\n\n    Foo[] enumValues();\n\n    int intValue();\n\n    int[] intValues();\n\n    long longValue();\n\n    long[] longValues();\n\n    byte byteValue();\n\n    byte[] byteValues();\n\n    short shortValue();\n\n    short[] shortValues();\n\n    float floatValue();\n\n    float[] floatValues();\n\n    double doubleValue();\n\n    double[] doubleValues();\n\n    boolean booleanValue();\n\n    boolean[] booleanValues();\n\n    char charValue();\n\n    char[] charValues();\n  }\n\n  private enum Foo {\n    BAR,\n    BAZ,\n    BAH;\n  }\n\n  @MultiValueAnnotation(\n      classValue = InsideClassA.class,\n      classValues = {InsideClassA.class, InsideClassB.class},\n      genericClassValue = GenericClass.class,\n      insideAnnotationValue = @InsideAnnotation(19),\n      insideAnnotationValues = {@InsideAnnotation(20), @InsideAnnotation(21)},\n      stringValue = \"hello\",\n      stringValues = {\"it's\", \"me\"},\n      enumValue = Foo.BAR,\n      enumValues = {Foo.BAZ, Foo.BAH},\n      intValue = 5,\n      intValues = {1, 2},\n      longValue = 6L,\n      longValues = {3L, 4L},\n      byteValue = (byte) 7,\n      byteValues = {(byte) 8, (byte) 9},\n      shortValue = (short) 10,\n      shortValues = {(short) 11, (short) 12},\n      floatValue = 13F,\n      floatValues = {14F, 15F},\n      doubleValue = 16D,\n      doubleValues = {17D, 18D},\n      booleanValue = true,\n      booleanValues = {true, false},\n      charValue = 'a',\n      charValues = {'b', 'c'})\n  private static class AnnotatedClass {}\n\n  @Rule public final CompilationRule compilation = new CompilationRule();\n\n  private Elements elements;\n  private Types types;\n  private AnnotationMirror annotationMirror;\n\n  @Before\n  public void setUp() {\n    elements = compilation.getElements();\n    types = compilation.getTypes();\n    TypeElement annotatedClass = getTypeElement(AnnotatedClass.class);\n    annotationMirror =\n        MoreElements.getAnnotationMirror(annotatedClass, MultiValueAnnotation.class).get();\n  }\n\n  @Test\n  public void getTypeMirror() {\n    TypeElement insideClassA = getTypeElement(InsideClassA.class);\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"classValue\");\n    assertThat(AnnotationValues.getTypeMirror(value).asElement()).isEqualTo(insideClassA);\n  }\n\n  @Test\n  public void getTypeMirrorGenericClass() {\n    TypeElement genericClass = getTypeElement(GenericClass.class);\n    AnnotationValue gvalue =\n        AnnotationMirrors.getAnnotationValue(annotationMirror, \"genericClassValue\");\n    assertThat(AnnotationValues.getTypeMirror(gvalue).asElement()).isEqualTo(genericClass);\n  }\n\n  @Test\n  public void getTypeMirrors() {\n    TypeMirror insideClassA = getTypeElement(InsideClassA.class).asType();\n    TypeMirror insideClassB = getTypeElement(InsideClassB.class).asType();\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"classValues\");\n    ImmutableList<DeclaredType> valueElements = AnnotationValues.getTypeMirrors(value);\n    assertThat(valueElements)\n        .comparingElementsUsing(Correspondence.from(types::isSameType, \"has Same Type\"))\n        .containsExactly(insideClassA, insideClassB)\n        .inOrder();\n  }\n\n  @Test\n  public void getAnnotationMirror() {\n    TypeElement insideAnnotation = getTypeElement(InsideAnnotation.class);\n    AnnotationValue value =\n        AnnotationMirrors.getAnnotationValue(annotationMirror, \"insideAnnotationValue\");\n    AnnotationMirror annotationMirror = AnnotationValues.getAnnotationMirror(value);\n    assertThat(annotationMirror.getAnnotationType().asElement()).isEqualTo(insideAnnotation);\n    assertThat(AnnotationMirrors.getAnnotationValue(annotationMirror, \"value\").getValue())\n        .isEqualTo(19);\n  }\n\n  @Test\n  public void getAnnotationMirrors() {\n    TypeElement insideAnnotation = getTypeElement(InsideAnnotation.class);\n    AnnotationValue value =\n        AnnotationMirrors.getAnnotationValue(annotationMirror, \"insideAnnotationValues\");\n    ImmutableList<AnnotationMirror> annotationMirrors =\n        AnnotationValues.getAnnotationMirrors(value);\n    ImmutableList<Element> valueElements =\n        annotationMirrors.stream()\n            .map(AnnotationMirror::getAnnotationType)\n            .map(DeclaredType::asElement)\n            .collect(toImmutableList());\n    assertThat(valueElements).containsExactly(insideAnnotation, insideAnnotation);\n    ImmutableList<Object> valuesStoredInAnnotation =\n        annotationMirrors.stream()\n            .map(\n                annotationMirror ->\n                    AnnotationMirrors.getAnnotationValue(annotationMirror, \"value\").getValue())\n            .collect(toImmutableList());\n    assertThat(valuesStoredInAnnotation).containsExactly(20, 21).inOrder();\n  }\n\n  @Test\n  public void getString() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"stringValue\");\n    assertThat(AnnotationValues.getString(value)).isEqualTo(\"hello\");\n  }\n\n  @Test\n  public void getStrings() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"stringValues\");\n    assertThat(AnnotationValues.getStrings(value)).containsExactly(\"it's\", \"me\").inOrder();\n  }\n\n  @Test\n  public void getEnum() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"enumValue\");\n    assertThat(AnnotationValues.getEnum(value)).isEqualTo(value.getValue());\n  }\n\n  @Test\n  public void getEnums() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"enumValues\");\n    assertThat(getEnumNames(AnnotationValues.getEnums(value)))\n        .containsExactly(Foo.BAZ.name(), Foo.BAH.name())\n        .inOrder();\n  }\n\n  @Test\n  public void getAnnotationValues() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"intValues\");\n    ImmutableList<AnnotationValue> values = AnnotationValues.getAnnotationValues(value);\n    assertThat(values)\n        .comparingElementsUsing(Correspondence.transforming(AnnotationValue::getValue, \"has value\"))\n        .containsExactly(1, 2)\n        .inOrder();\n  }\n\n  @Test\n  public void getInt() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"intValue\");\n    assertThat(AnnotationValues.getInt(value)).isEqualTo(5);\n  }\n\n  @Test\n  public void getInts() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"intValues\");\n    assertThat(AnnotationValues.getInts(value)).containsExactly(1, 2).inOrder();\n  }\n\n  @Test\n  public void getLong() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"longValue\");\n    assertThat(AnnotationValues.getLong(value)).isEqualTo(6L);\n  }\n\n  @Test\n  public void getLongs() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"longValues\");\n    assertThat(AnnotationValues.getLongs(value)).containsExactly(3L, 4L).inOrder();\n  }\n\n  @Test\n  public void getByte() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"byteValue\");\n    assertThat(AnnotationValues.getByte(value)).isEqualTo((byte) 7);\n  }\n\n  @Test\n  public void getBytes() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"byteValues\");\n    assertThat(AnnotationValues.getBytes(value)).containsExactly((byte) 8, (byte) 9).inOrder();\n  }\n\n  @Test\n  public void getShort() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"shortValue\");\n    assertThat(AnnotationValues.getShort(value)).isEqualTo((short) 10);\n  }\n\n  @Test\n  public void getShorts() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"shortValues\");\n    assertThat(AnnotationValues.getShorts(value)).containsExactly((short) 11, (short) 12).inOrder();\n  }\n\n  @Test\n  public void getFloat() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"floatValue\");\n    assertThat(AnnotationValues.getFloat(value)).isEqualTo(13F);\n  }\n\n  @Test\n  public void getFloats() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"floatValues\");\n    assertThat(AnnotationValues.getFloats(value)).containsExactly(14F, 15F).inOrder();\n  }\n\n  @Test\n  public void getDouble() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"doubleValue\");\n    assertThat(AnnotationValues.getDouble(value)).isEqualTo(16D);\n  }\n\n  @Test\n  public void getDoubles() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"doubleValues\");\n    assertThat(AnnotationValues.getDoubles(value)).containsExactly(17D, 18D).inOrder();\n  }\n\n  @Test\n  public void getBoolean() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"booleanValue\");\n    assertThat(AnnotationValues.getBoolean(value)).isTrue();\n  }\n\n  @Test\n  public void getBooleans() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"booleanValues\");\n    assertThat(AnnotationValues.getBooleans(value)).containsExactly(true, false).inOrder();\n  }\n\n  @Test\n  public void getChar() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"charValue\");\n    assertThat(AnnotationValues.getChar(value)).isEqualTo('a');\n  }\n\n  @Test\n  public void getChars() {\n    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, \"charValues\");\n    assertThat(AnnotationValues.getChars(value)).containsExactly('b', 'c').inOrder();\n  }\n\n  @Test\n  public void toSourceString() {\n    ImmutableMap<String, String> inputs =\n        ImmutableMap.<String, String>builder()\n            .put(\"classValue\", \"com.google.auto.common.AnnotationValuesTest.InsideClassA.class\")\n            .put(\n                \"classValues\",\n                \"{com.google.auto.common.AnnotationValuesTest.InsideClassA.class,\"\n                    + \" com.google.auto.common.AnnotationValuesTest.InsideClassB.class}\")\n            .put(\n                \"genericClassValue\",\n                \"com.google.auto.common.AnnotationValuesTest.GenericClass.class\")\n            .put(\n                \"insideAnnotationValue\",\n                \"@com.google.auto.common.AnnotationValuesTest.InsideAnnotation(19)\")\n            .put(\n                \"insideAnnotationValues\",\n                \"{@com.google.auto.common.AnnotationValuesTest.InsideAnnotation(20),\"\n                    + \" @com.google.auto.common.AnnotationValuesTest.InsideAnnotation(21)}\")\n            .put(\"stringValue\", \"\\\"hello\\\"\")\n            .put(\"stringValues\", \"{\\\"it\\\\'s\\\", \\\"me\\\"}\")\n            .put(\"enumValue\", \"com.google.auto.common.AnnotationValuesTest.Foo.BAR\")\n            .put(\n                \"enumValues\",\n                \"{com.google.auto.common.AnnotationValuesTest.Foo.BAZ,\"\n                    + \" com.google.auto.common.AnnotationValuesTest.Foo.BAH}\")\n            .put(\"intValue\", \"5\")\n            .put(\"intValues\", \"{1, 2}\")\n            .put(\"longValue\", \"6L\")\n            .put(\"longValues\", \"{3L, 4L}\")\n            .put(\"byteValue\", \"(byte) 7\")\n            .put(\"byteValues\", \"{(byte) 8, (byte) 9}\")\n            .put(\"shortValue\", \"(short) 10\")\n            .put(\"shortValues\", \"{(short) 11, (short) 12}\")\n            .put(\"floatValue\", \"13.0F\")\n            .put(\"floatValues\", \"{14.0F, 15.0F}\")\n            .put(\"doubleValue\", \"16.0\")\n            .put(\"doubleValues\", \"{17.0, 18.0}\")\n            .put(\"booleanValue\", \"true\")\n            .put(\"booleanValues\", \"{true, false}\")\n            .put(\"charValue\", \"'a'\")\n            .put(\"charValues\", \"{'b', 'c'}\")\n            .build();\n    inputs.forEach(\n        (name, expected) ->\n            assertThat(\n                    AnnotationValues.toString(\n                        AnnotationMirrors.getAnnotationValue(annotationMirror, name)))\n                .isEqualTo(expected));\n    assertThat(AnnotationMirrors.toString(annotationMirror))\n        .isEqualTo(\n            inputs.entrySet().stream()\n                .map(e -> e.getKey() + \" = \" + e.getValue())\n                .collect(\n                    joining(\n                        \", \",\n                        \"@com.google.auto.common.AnnotationValuesTest.MultiValueAnnotation(\",\n                        \")\")));\n  }\n\n  private TypeElement getTypeElement(Class<?> clazz) {\n    return elements.getTypeElement(clazz.getCanonicalName());\n  }\n\n  private static ImmutableList<String> getEnumNames(ImmutableList<VariableElement> values) {\n    return values.stream()\n        .map(VariableElement::getSimpleName)\n        .map(Name::toString)\n        .collect(toImmutableList());\n  }\n}\n"
  },
  {
    "path": "common/src/test/java/com/google/auto/common/BasicAnnotationProcessorTest.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport static com.google.common.base.StandardSystemProperty.JAVA_SPECIFICATION_VERSION;\nimport static com.google.common.collect.Multimaps.transformValues;\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.common.truth.TruthJUnit.assume;\nimport static com.google.testing.compile.CompilationSubject.assertThat;\nimport static com.google.testing.compile.Compiler.javac;\nimport static javax.tools.Diagnostic.Kind.ERROR;\n\nimport com.google.auto.common.BasicAnnotationProcessor.ProcessingStep;\nimport com.google.auto.common.BasicAnnotationProcessor.Step;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.ImmutableSetMultimap;\nimport com.google.common.collect.SetMultimap;\nimport com.google.common.truth.Correspondence;\nimport com.google.errorprone.annotations.CanIgnoreReturnValue;\nimport com.google.testing.compile.Compilation;\nimport com.google.testing.compile.CompilationRule;\nimport com.google.testing.compile.JavaFileObjects;\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.lang.annotation.Annotation;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Objects;\nimport javax.annotation.processing.Filer;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.Name;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.util.Elements;\nimport javax.tools.JavaFileObject;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic class BasicAnnotationProcessorTest {\n\n  private abstract static class BaseAnnotationProcessor extends BasicAnnotationProcessor {\n\n    static final String ENCLOSING_CLASS_NAME =\n        BasicAnnotationProcessorTest.class.getCanonicalName();\n\n    @Override\n    public final SourceVersion getSupportedSourceVersion() {\n      return SourceVersion.latestSupported();\n    }\n  }\n\n  @Retention(RetentionPolicy.SOURCE)\n  public @interface RequiresGeneratedCode {}\n\n  @Retention(RetentionPolicy.SOURCE)\n  @Target(ElementType.TYPE_PARAMETER)\n  public @interface TypeParameterRequiresGeneratedCode {}\n\n  /**\n   * Rejects elements unless the class generated by {@link GeneratesCode}'s processor is present.\n   */\n  private static class RequiresGeneratedCodeProcessor extends BaseAnnotationProcessor {\n\n    int rejectedRounds;\n    final ImmutableList.Builder<ImmutableSetMultimap<String, Element>> processArguments =\n        ImmutableList.builder();\n\n    @Override\n    protected Iterable<? extends Step> steps() {\n      return ImmutableList.of(\n          new Step() {\n            @Override\n            public ImmutableSet<? extends Element> process(\n                ImmutableSetMultimap<String, Element> elementsByAnnotation) {\n              processArguments.add(elementsByAnnotation);\n              TypeElement requiredClass =\n                  processingEnv.getElementUtils().getTypeElement(\"test.SomeGeneratedClass\");\n              if (requiredClass == null) {\n                rejectedRounds++;\n                return ImmutableSet.copyOf(elementsByAnnotation.values());\n              }\n              generateClass(processingEnv.getFiler(), \"GeneratedByRequiresGeneratedCodeProcessor\");\n              return ImmutableSet.of();\n            }\n\n            @Override\n            public ImmutableSet<String> annotations() {\n              return ImmutableSet.of(\n                  ENCLOSING_CLASS_NAME + \".RequiresGeneratedCode\",\n                  ENCLOSING_CLASS_NAME + \".TypeParameterRequiresGeneratedCode\");\n            }\n          });\n    }\n\n    ImmutableList<ImmutableSetMultimap<String, Element>> processArguments() {\n      return processArguments.build();\n    }\n  }\n\n  @Retention(RetentionPolicy.SOURCE)\n  @Target(ElementType.METHOD)\n  public @interface OneMethodAtATime {}\n\n  private static class OneMethodAtATimeProcessor extends BaseAnnotationProcessor {\n\n    int rejectedRounds;\n    final ImmutableList.Builder<ImmutableSetMultimap<String, Element>> processArguments =\n        ImmutableList.builder();\n\n    @Override\n    protected Iterable<? extends Step> steps() {\n      return ImmutableSet.of(\n          new Step() {\n            @Override\n            public ImmutableSet<? extends Element> process(\n                ImmutableSetMultimap<String, Element> elementsByAnnotation) {\n              processArguments.add(elementsByAnnotation);\n              int numberOfAnnotatedElements = elementsByAnnotation.size();\n              if (numberOfAnnotatedElements == 0) {\n                return ImmutableSet.of();\n              }\n\n              generateClass(\n                  processingEnv.getFiler(),\n                  \"GeneratedByOneMethodAtATimeProcessor_\"\n                      + elementsByAnnotation.values().iterator().next().getSimpleName());\n              if (numberOfAnnotatedElements > 1) {\n                rejectedRounds++;\n              }\n              return ImmutableSet.copyOf(\n                  elementsByAnnotation.values().asList().subList(1, numberOfAnnotatedElements));\n            }\n\n            @Override\n            public ImmutableSet<String> annotations() {\n              return ImmutableSet.of(ENCLOSING_CLASS_NAME + \".OneMethodAtATime\");\n            }\n          });\n    }\n\n    ImmutableList<ImmutableSetMultimap<String, Element>> processArguments() {\n      return processArguments.build();\n    }\n  }\n\n  /**\n   * This processor processes the OneMethodAtATime annotated methods, one at a time in the following\n   * fashion. If the number of annotated methods is more than two, the second annotated method is\n   * processed and the rest are deferred. Otherwise, the first annotated method is processed.\n   */\n  private static class OneOverloadedMethodAtATimeProcessor extends BaseAnnotationProcessor {\n\n    int rejectedRounds;\n    final ImmutableList.Builder<ImmutableSetMultimap<String, Element>> processArguments =\n        ImmutableList.builder();\n\n    @Override\n    protected Iterable<? extends Step> steps() {\n      return ImmutableSet.of(\n          new Step() {\n            @Override\n            public ImmutableSet<? extends Element> process(\n                ImmutableSetMultimap<String, Element> elementsByAnnotation) {\n              processArguments.add(elementsByAnnotation);\n\n              List<Element> annotatedElements = new ArrayList<>(elementsByAnnotation.values());\n              int numberOfAnnotatedElements = annotatedElements.size();\n              if (numberOfAnnotatedElements == 0) {\n                return ImmutableSet.of();\n              }\n              if (numberOfAnnotatedElements > 1) {\n                rejectedRounds++;\n              }\n\n              Name nameOfToBeProcessedElement;\n              ImmutableSet<? extends Element> rejectedElements;\n              if (numberOfAnnotatedElements > 2) {\n                // Skip the first Element\n                nameOfToBeProcessedElement = annotatedElements.get(1).getSimpleName();\n                annotatedElements.remove(1);\n                rejectedElements = ImmutableSet.copyOf(annotatedElements);\n              } else {\n                nameOfToBeProcessedElement = annotatedElements.get(0).getSimpleName();\n                annotatedElements.remove(0);\n                rejectedElements = ImmutableSet.copyOf(annotatedElements);\n              }\n\n              generateClass(\n                  processingEnv.getFiler(),\n                  String.format(\n                      \"GeneratedByOneMethodAtATimeProcessor_%d_%s\",\n                      numberOfAnnotatedElements > 1 ? rejectedRounds : rejectedRounds + 1,\n                      Objects.requireNonNull(nameOfToBeProcessedElement)));\n\n              return Objects.requireNonNull(rejectedElements);\n            }\n\n            @Override\n            public ImmutableSet<String> annotations() {\n              return ImmutableSet.of(ENCLOSING_CLASS_NAME + \".OneMethodAtATime\");\n            }\n          });\n    }\n\n    ImmutableList<ImmutableSetMultimap<String, Element>> processArguments() {\n      return processArguments.build();\n    }\n  }\n\n  @Retention(RetentionPolicy.SOURCE)\n  public @interface GeneratesCode {}\n\n  /** Generates a class called {@code test.SomeGeneratedClass}. */\n  public static class GeneratesCodeProcessor extends BaseAnnotationProcessor {\n    @Override\n    protected Iterable<? extends Step> steps() {\n      return ImmutableList.of(\n          new Step() {\n            @Override\n            public ImmutableSet<? extends Element> process(\n                ImmutableSetMultimap<String, Element> elementsByAnnotation) {\n              generateClass(processingEnv.getFiler(), \"SomeGeneratedClass\");\n              return ImmutableSet.of();\n            }\n\n            @Override\n            public ImmutableSet<String> annotations() {\n              return ImmutableSet.of(ENCLOSING_CLASS_NAME + \".GeneratesCode\");\n            }\n          });\n    }\n  }\n\n  public @interface AnAnnotation {}\n\n  /** When annotating a type {@code Foo}, generates a class called {@code FooXYZ}. */\n  public static class AnAnnotationProcessor extends BaseAnnotationProcessor {\n\n    @Override\n    protected Iterable<? extends Step> steps() {\n      return ImmutableList.of(\n          new Step() {\n            @Override\n            public ImmutableSet<Element> process(\n                ImmutableSetMultimap<String, Element> elementsByAnnotation) {\n              for (Element element : elementsByAnnotation.values()) {\n                generateClass(processingEnv.getFiler(), element.getSimpleName() + \"XYZ\");\n              }\n              return ImmutableSet.of();\n            }\n\n            @Override\n            public ImmutableSet<String> annotations() {\n              return ImmutableSet.of(ENCLOSING_CLASS_NAME + \".AnAnnotation\");\n            }\n          });\n    }\n  }\n\n  /** An annotation which causes an annotation processing error. */\n  public @interface CauseError {}\n\n  /** Report an error for any class annotated. */\n  public static class CauseErrorProcessor extends BaseAnnotationProcessor {\n\n    @Override\n    protected Iterable<? extends Step> steps() {\n      return ImmutableList.of(\n          new Step() {\n            @Override\n            public ImmutableSet<Element> process(\n                ImmutableSetMultimap<String, Element> elementsByAnnotation) {\n              for (Element e : elementsByAnnotation.values()) {\n                processingEnv.getMessager().printMessage(ERROR, \"purposeful error\", e);\n              }\n              return ImmutableSet.copyOf(elementsByAnnotation.values());\n            }\n\n            @Override\n            public ImmutableSet<String> annotations() {\n              return ImmutableSet.of(ENCLOSING_CLASS_NAME + \".CauseError\");\n            }\n          });\n    }\n  }\n\n  public static class MissingAnnotationProcessor extends BaseAnnotationProcessor {\n\n    private ImmutableSetMultimap<String, Element> elementsByAnnotation;\n\n    @Override\n    protected Iterable<? extends Step> steps() {\n      return ImmutableList.of(\n          new Step() {\n            @Override\n            public ImmutableSet<Element> process(\n                ImmutableSetMultimap<String, Element> elementsByAnnotation) {\n              MissingAnnotationProcessor.this.elementsByAnnotation = elementsByAnnotation;\n              for (Element element : elementsByAnnotation.values()) {\n                generateClass(processingEnv.getFiler(), element.getSimpleName() + \"XYZ\");\n              }\n              return ImmutableSet.of();\n            }\n\n            @Override\n            public ImmutableSet<String> annotations() {\n              return ImmutableSet.of(\n                  \"test.SomeNonExistentClass\", ENCLOSING_CLASS_NAME + \".AnAnnotation\");\n            }\n          });\n    }\n\n    ImmutableSetMultimap<String, Element> getElementsByAnnotation() {\n      return elementsByAnnotation;\n    }\n  }\n\n  @SuppressWarnings(\"deprecation\") // Deprecated ProcessingStep is being explicitly tested.\n  static final class MultiAnnotationProcessingStep implements ProcessingStep {\n\n    private SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation;\n\n    @Override\n    public ImmutableSet<? extends Class<? extends Annotation>> annotations() {\n      return ImmutableSet.of(AnAnnotation.class, ReferencesAClass.class);\n    }\n\n    @Override\n    public ImmutableSet<? extends Element> process(\n        SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {\n      this.elementsByAnnotation = elementsByAnnotation;\n      return ImmutableSet.of();\n    }\n\n    SetMultimap<Class<? extends Annotation>, Element> getElementsByAnnotation() {\n      return elementsByAnnotation;\n    }\n  }\n\n  @Retention(RetentionPolicy.SOURCE)\n  public @interface ReferencesAClass {\n    Class<?> value();\n  }\n\n  @Rule public CompilationRule compilation = new CompilationRule();\n\n  private void requiresGeneratedCodeDeferralTest(\n      JavaFileObject dependentTestFileObject, JavaFileObject generatesCodeFileObject) {\n    RequiresGeneratedCodeProcessor requiresGeneratedCodeProcessor =\n        new RequiresGeneratedCodeProcessor();\n    Compilation compilation =\n        javac()\n            .withProcessors(requiresGeneratedCodeProcessor, new GeneratesCodeProcessor())\n            .compile(dependentTestFileObject, generatesCodeFileObject);\n    assertThat(compilation).succeeded();\n    assertThat(compilation).generatedSourceFile(\"test.GeneratedByRequiresGeneratedCodeProcessor\");\n    assertThat(requiresGeneratedCodeProcessor.rejectedRounds).isEqualTo(0);\n  }\n\n  private void requiresGeneratedCodeDeferralTest(JavaFileObject dependentTestFileObject) {\n    JavaFileObject generatesCodeFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassB\",\n            \"package test;\",\n            \"\",\n            \"@\" + GeneratesCode.class.getCanonicalName(),\n            \"public class ClassB {}\");\n    requiresGeneratedCodeDeferralTest(dependentTestFileObject, generatesCodeFileObject);\n  }\n\n  @Test\n  public void properlyDefersProcessing_typeElement() {\n    JavaFileObject dependentTestFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassA\",\n            \"package test;\",\n            \"\",\n            \"@\" + RequiresGeneratedCode.class.getCanonicalName(),\n            \"public class ClassA {\",\n            \"  SomeGeneratedClass sgc;\",\n            \"}\");\n    requiresGeneratedCodeDeferralTest(dependentTestFileObject);\n  }\n\n  @Test\n  public void properlyDefersProcessing_packageElement() {\n    JavaFileObject dependentTestFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassA\",\n            \"package test;\",\n            \"\",\n            \"@\" + GeneratesCode.class.getCanonicalName(),\n            \"public class ClassA {\",\n            \"}\");\n    JavaFileObject generatesCodeFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.package-info\",\n            \"@\" + RequiresGeneratedCode.class.getCanonicalName(),\n            \"@\" + ReferencesAClass.class.getCanonicalName() + \"(SomeGeneratedClass.class)\",\n            \"package test;\");\n    requiresGeneratedCodeDeferralTest(dependentTestFileObject, generatesCodeFileObject);\n  }\n\n  @Test\n  public void properlyDefersProcessing_argumentElement() {\n    JavaFileObject dependentTestFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassA\",\n            \"package test;\",\n            \"\",\n            \"public class ClassA {\",\n            \"  SomeGeneratedClass sgc;\",\n            \"  public void myMethod(@\"\n                + RequiresGeneratedCode.class.getCanonicalName()\n                + \" int myInt)\",\n            \"  {}\",\n            \"}\");\n    JavaFileObject generatesCodeFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassB\",\n            \"package test;\",\n            \"\",\n            \"public class ClassB {\",\n            \"  public void myMethod(@\" + GeneratesCode.class.getCanonicalName() + \" int myInt) {}\",\n            \"}\");\n    requiresGeneratedCodeDeferralTest(dependentTestFileObject, generatesCodeFileObject);\n  }\n\n  @Test\n  public void properlyDefersProcessing_recordComponent() {\n    double version = Double.parseDouble(Objects.requireNonNull(JAVA_SPECIFICATION_VERSION.value()));\n    assume().that(version).isAtLeast(16.0);\n    JavaFileObject dependentTestFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.RecordA\",\n            \"package test;\",\n            \"\",\n            \"public record RecordA( @\"\n                + RequiresGeneratedCode.class.getCanonicalName()\n                + \" SomeGeneratedClass sgc) {\",\n            \"}\");\n    requiresGeneratedCodeDeferralTest(dependentTestFileObject);\n  }\n\n  @Test\n  public void properlyDefersProcessing_typeParameter() {\n    JavaFileObject dependentTestFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassA\",\n            \"package test;\",\n            \"\",\n            \"public class ClassA <@\"\n                + TypeParameterRequiresGeneratedCode.class.getCanonicalName()\n                + \" T extends SomeGeneratedClass> {\",\n            \"}\");\n    requiresGeneratedCodeDeferralTest(dependentTestFileObject);\n  }\n\n  @Test\n  public void properlyDefersProcessing_methodTypeParameter() {\n    JavaFileObject dependentTestFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassA\",\n            \"package test;\",\n            \"\",\n            \"public class ClassA {\",\n            \"  <@\"\n                + TypeParameterRequiresGeneratedCode.class.getCanonicalName()\n                + \" T extends SomeGeneratedClass> void foo(T t) {}\",\n            \"}\");\n    requiresGeneratedCodeDeferralTest(dependentTestFileObject);\n  }\n\n  @Test\n  public void properlyDefersProcessing_nestedTypeValidBeforeOuterType() {\n    JavaFileObject source =\n        JavaFileObjects.forSourceLines(\n            \"test.ValidInRound2\",\n            \"package test;\",\n            \"\",\n            \"@\" + AnAnnotation.class.getCanonicalName(),\n            \"public class ValidInRound2 {\",\n            \"  ValidInRound1XYZ vir1xyz;\",\n            \"  @\" + AnAnnotation.class.getCanonicalName(),\n            \"  static class ValidInRound1 {}\",\n            \"}\");\n    Compilation compilation = javac().withProcessors(new AnAnnotationProcessor()).compile(source);\n    assertThat(compilation).succeeded();\n    assertThat(compilation).generatedSourceFile(\"test.ValidInRound2XYZ\");\n  }\n\n  @Test\n  public void properlyDefersProcessing_rejectsTypeElement() {\n    JavaFileObject classAFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassA\",\n            \"package test;\",\n            \"\",\n            \"@\" + RequiresGeneratedCode.class.getCanonicalName(),\n            \"public class ClassA {\",\n            \"  @\" + AnAnnotation.class.getCanonicalName(),\n            \"  public void method() {}\",\n            \"}\");\n    RequiresGeneratedCodeProcessor requiresGeneratedCodeProcessor =\n        requiresGeneratedCodeRejectionTest(classAFileObject);\n\n    // Re b/118372780: Assert that the right deferred elements are passed back, and not any enclosed\n    // elements annotated with annotations from a different step.\n    assertThat(requiresGeneratedCodeProcessor.processArguments())\n        .comparingElementsUsing(setMultimapValuesByString())\n        .containsExactly(\n            ImmutableSetMultimap.of(RequiresGeneratedCode.class.getCanonicalName(), \"test.ClassA\"),\n            ImmutableSetMultimap.of(RequiresGeneratedCode.class.getCanonicalName(), \"test.ClassA\"))\n        .inOrder();\n  }\n\n  @Test\n  public void properlyDefersProcessing_rejectsTypeParameterElement() {\n    JavaFileObject classAFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassA\",\n            \"package test;\",\n            \"\",\n            \"public class ClassA<@\"\n                + TypeParameterRequiresGeneratedCode.class.getCanonicalName()\n                + \" T> {\",\n            \"  @\" + AnAnnotation.class.getCanonicalName(),\n            \"  public void method() {}\",\n            \"}\");\n    requiresGeneratedCodeRejectionTest(classAFileObject);\n  }\n\n  @Test\n  public void properlyDefersProcessing_rejectsArgumentElement() {\n    JavaFileObject classAFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassA\",\n            \"package test;\",\n            \"\",\n            \"public class ClassA {\",\n            \"  public void myMethod(@\"\n                + RequiresGeneratedCode.class.getCanonicalName()\n                + \" int myInt)\",\n            \"  {}\",\n            \"}\");\n    requiresGeneratedCodeRejectionTest(classAFileObject);\n  }\n\n  @Test\n  public void properlyDefersProcessing_rejectsField() {\n    double version = Double.parseDouble(Objects.requireNonNull(JAVA_SPECIFICATION_VERSION.value()));\n    assume().that(version).isAtLeast(16.0);\n    JavaFileObject classAFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassA\",\n            \"package test;\",\n            \"\",\n            \"public class ClassA {\",\n            \"@\" + RequiresGeneratedCode.class.getCanonicalName() + \" String s;\",\n            \"}\");\n    requiresGeneratedCodeRejectionTest(classAFileObject);\n  }\n\n  @Test\n  public void properlyDefersProcessing_rejectsRecordComponent() {\n    double version = Double.parseDouble(Objects.requireNonNull(JAVA_SPECIFICATION_VERSION.value()));\n    assume().that(version).isAtLeast(16.0);\n    JavaFileObject classAFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.RecordA\",\n            \"package test;\",\n            \"\",\n            \"public record RecordA(@\"\n                + RequiresGeneratedCode.class.getCanonicalName()\n                + \" String s) {\",\n            \"}\");\n    requiresGeneratedCodeRejectionTest(classAFileObject);\n  }\n\n  @Test\n  public void properlyDefersProcessing_rejectsTypeParameterElementInMethod() {\n    JavaFileObject classAFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassA\",\n            \"package test;\",\n            \"\",\n            \"public class ClassA {\",\n            \"  @\" + AnAnnotation.class.getCanonicalName(),\n            \"  <@\"\n                + TypeParameterRequiresGeneratedCode.class.getCanonicalName()\n                + \" T> void method(T t) {}\",\n            \"}\");\n    requiresGeneratedCodeRejectionTest(classAFileObject);\n  }\n\n  @CanIgnoreReturnValue\n  private RequiresGeneratedCodeProcessor requiresGeneratedCodeRejectionTest(\n      JavaFileObject classAFileObject) {\n    JavaFileObject classBFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassB\",\n            \"package test;\",\n            \"\",\n            \"@\" + GeneratesCode.class.getCanonicalName(),\n            \"public class ClassB {}\");\n    RequiresGeneratedCodeProcessor requiresGeneratedCodeProcessor =\n        new RequiresGeneratedCodeProcessor();\n    Compilation compilation =\n        javac()\n            .withProcessors(requiresGeneratedCodeProcessor, new GeneratesCodeProcessor())\n            .compile(classAFileObject, classBFileObject);\n    assertThat(compilation).succeeded();\n    assertThat(compilation).generatedSourceFile(\"test.GeneratedByRequiresGeneratedCodeProcessor\");\n    assertThat(requiresGeneratedCodeProcessor.rejectedRounds).isEqualTo(1);\n    return requiresGeneratedCodeProcessor;\n  }\n\n  private static <K, V>\n      Correspondence<SetMultimap<K, V>, SetMultimap<K, String>> setMultimapValuesByString() {\n    return Correspondence.from(\n        (actual, expected) ->\n            ImmutableSetMultimap.copyOf(transformValues(actual, Object::toString)).equals(expected),\n        \"is equivalent comparing multimap values by `toString()` to\");\n  }\n\n  @Test\n  public void properlyDefersProcessing_stepRejectingExecutableElements() {\n    JavaFileObject classAFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassA\",\n            \"package test;\",\n            \"\",\n            \"public class ClassA {\",\n            \"  @\" + OneMethodAtATime.class.getCanonicalName(),\n            \"  public void method0() {}\",\n            \"  @\" + OneMethodAtATime.class.getCanonicalName(),\n            \"  public void method1() {}\",\n            \"  @\" + OneMethodAtATime.class.getCanonicalName(),\n            \"  public void method2() {}\",\n            \"}\");\n    OneMethodAtATimeProcessor oneMethodAtATimeProcessor = new OneMethodAtATimeProcessor();\n    Compilation compilation =\n        javac().withProcessors(oneMethodAtATimeProcessor).compile(classAFileObject);\n\n    assertThat(compilation).succeeded();\n    assertThat(oneMethodAtATimeProcessor.rejectedRounds).isEqualTo(2);\n\n    assertThat(oneMethodAtATimeProcessor.processArguments())\n        .comparingElementsUsing(setMultimapValuesByString())\n        .containsExactly(\n            ImmutableSetMultimap.of(\n                OneMethodAtATime.class.getCanonicalName(), \"method0()\",\n                OneMethodAtATime.class.getCanonicalName(), \"method1()\",\n                OneMethodAtATime.class.getCanonicalName(), \"method2()\"),\n            ImmutableSetMultimap.of(\n                OneMethodAtATime.class.getCanonicalName(), \"method1()\",\n                OneMethodAtATime.class.getCanonicalName(), \"method2()\"),\n            ImmutableSetMultimap.of(OneMethodAtATime.class.getCanonicalName(), \"method2()\"))\n        .inOrder();\n  }\n\n  @Test\n  public void properlyDefersProcessing_stepRejectingOverloadedExecutableElements() {\n    JavaFileObject classAFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassA\",\n            \"package test;\",\n            \"\",\n            \"public class ClassA {\",\n            \"  @\" + OneMethodAtATime.class.getCanonicalName(),\n            \"  public void overloadedMethod(int x) {}\",\n            \"  @\" + OneMethodAtATime.class.getCanonicalName(),\n            \"  public void overloadedMethod(float x) {}\",\n            \"  @\" + OneMethodAtATime.class.getCanonicalName(),\n            \"  public void overloadedMethod(double x) {}\",\n            \"}\");\n    OneOverloadedMethodAtATimeProcessor oneOverloadedMethodAtATimeProcessor =\n        new OneOverloadedMethodAtATimeProcessor();\n    Compilation compilation =\n        javac().withProcessors(oneOverloadedMethodAtATimeProcessor).compile(classAFileObject);\n\n    assertThat(compilation).succeeded();\n    assertThat(oneOverloadedMethodAtATimeProcessor.rejectedRounds).isEqualTo(2);\n\n    assertThat(oneOverloadedMethodAtATimeProcessor.processArguments())\n        .comparingElementsUsing(setMultimapValuesByString())\n        .containsExactly(\n            ImmutableSetMultimap.of(\n                OneMethodAtATime.class.getCanonicalName(), \"overloadedMethod(int)\",\n                OneMethodAtATime.class.getCanonicalName(), \"overloadedMethod(float)\",\n                OneMethodAtATime.class.getCanonicalName(), \"overloadedMethod(double)\"),\n            ImmutableSetMultimap.of(\n                OneMethodAtATime.class.getCanonicalName(), \"overloadedMethod(int)\",\n                OneMethodAtATime.class.getCanonicalName(), \"overloadedMethod(double)\"),\n            ImmutableSetMultimap.of(\n                OneMethodAtATime.class.getCanonicalName(), \"overloadedMethod(double)\"))\n        .inOrder();\n  }\n\n  @Test\n  public void properlyDefersProcessing_stepAndIllFormedRejectingExecutableElements() {\n    JavaFileObject testFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassA\",\n            \"package test;\",\n            \"import java.util.Set;\",\n            \"import java.util.SortedSet;\",\n            \"\",\n            \"public class ClassA {\",\n            \"  @\" + OneMethodAtATime.class.getCanonicalName(),\n            \"  <C extends Set<String>> void overloadedMethod(C x) {}\",\n            \"  @\" + OneMethodAtATime.class.getCanonicalName(),\n            \"  <C extends SortedSet<String>> void overloadedMethod(C c) {}\",\n            \"  @\" + OneMethodAtATime.class.getCanonicalName(),\n            \"  void overloadedMethod(SomeGeneratedClass c) {}\",\n            \"  @\" + OneMethodAtATime.class.getCanonicalName(),\n            \"  void method0(SomeGeneratedClass c) {}\",\n            \"}\");\n\n    JavaFileObject generatesCodeFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassB\",\n            \"package test;\",\n            \"\",\n            \"@\" + GeneratesCode.class.getCanonicalName(),\n            \"public class ClassB {}\");\n\n    OneOverloadedMethodAtATimeProcessor oneOverloadedMethodAtATimeProcessor =\n        new OneOverloadedMethodAtATimeProcessor();\n    Compilation compilation =\n        javac()\n            .withProcessors(oneOverloadedMethodAtATimeProcessor, new GeneratesCodeProcessor())\n            .compile(testFileObject, generatesCodeFileObject);\n\n    assertThat(compilation).succeeded();\n    assertThat(oneOverloadedMethodAtATimeProcessor.rejectedRounds).isEqualTo(3);\n\n    assertThat(oneOverloadedMethodAtATimeProcessor.processArguments())\n        .comparingElementsUsing(setMultimapValuesByString())\n        .containsExactly(\n            ImmutableSetMultimap.of(\n                OneMethodAtATime.class.getCanonicalName(), \"<C>overloadedMethod(C)\",\n                OneMethodAtATime.class.getCanonicalName(), \"<C>overloadedMethod(C)\",\n                OneMethodAtATime.class.getCanonicalName(),\n                    \"overloadedMethod(test.SomeGeneratedClass)\",\n                OneMethodAtATime.class.getCanonicalName(), \"method0(test.SomeGeneratedClass)\"),\n            ImmutableSetMultimap.of(\n                OneMethodAtATime.class.getCanonicalName(), \"<C>overloadedMethod(C)\",\n                OneMethodAtATime.class.getCanonicalName(),\n                    \"overloadedMethod(test.SomeGeneratedClass)\",\n                OneMethodAtATime.class.getCanonicalName(), \"method0(test.SomeGeneratedClass)\"),\n            ImmutableSetMultimap.of(\n                OneMethodAtATime.class.getCanonicalName(), \"<C>overloadedMethod(C)\",\n                OneMethodAtATime.class.getCanonicalName(), \"method0(test.SomeGeneratedClass)\"),\n            ImmutableSetMultimap.of(\n                OneMethodAtATime.class.getCanonicalName(), \"method0(test.SomeGeneratedClass)\"))\n        .inOrder();\n  }\n\n  /**\n   * In the following example, at least open-jdk does not report the second method if {@code\n   * SomeGeneratedClass} references a {@link TypeKind#ERROR} when {@link\n   * RoundEnvironment#getElementsAnnotatedWith} is called, or even when {@link\n   * TypeElement#getEnclosedElements()} is called. Therefore, our implementation should be vigilant\n   * that the second method is captured for processing at some point.\n   *\n   * <p>Note that for a method to get \"hidden\" like this, it should reside after the ERROR\n   * referencing method, and it should not have any distinguishing characteristic like different\n   * name, different number of parameter, or a clear parameter type mismatch.\n   */\n  @Test\n  public void properlyDefersProcessing_errorTypeReferencingOverloadedMethods() {\n    JavaFileObject testFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassA\",\n            \"package test;\",\n            \"\",\n            \"public class ClassA {\",\n            \"  @\" + OneMethodAtATime.class.getCanonicalName(),\n            \"  void overloadedMethod(SomeGeneratedClass c) {}\",\n            \"  @\" + OneMethodAtATime.class.getCanonicalName(),\n            \"  void overloadedMethod(int c) {}\",\n            \"}\");\n\n    JavaFileObject generatesCodeFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassB\",\n            \"package test;\",\n            \"\",\n            \"@\" + GeneratesCode.class.getCanonicalName(),\n            \"public class ClassB {}\");\n\n    OneOverloadedMethodAtATimeProcessor oneOverloadedMethodAtATimeProcessor =\n        new OneOverloadedMethodAtATimeProcessor();\n    Compilation compilation =\n        javac()\n            .withProcessors(oneOverloadedMethodAtATimeProcessor, new GeneratesCodeProcessor())\n            .compile(testFileObject, generatesCodeFileObject);\n\n    assertThat(compilation).succeeded();\n    assertThat(oneOverloadedMethodAtATimeProcessor.rejectedRounds).isEqualTo(1);\n\n    assertThat(oneOverloadedMethodAtATimeProcessor.processArguments())\n        .comparingElementsUsing(setMultimapValuesByString())\n        .containsExactly(\n            ImmutableSetMultimap.of(\n                OneMethodAtATime.class.getCanonicalName(),\n                \"overloadedMethod(test.SomeGeneratedClass)\",\n                OneMethodAtATime.class.getCanonicalName(),\n                \"overloadedMethod(int)\"),\n            ImmutableSetMultimap.of(\n                OneMethodAtATime.class.getCanonicalName(), \"overloadedMethod(int)\"))\n        .inOrder();\n  }\n\n  @Test\n  public void properlySkipsMissingAnnotations_generatesClass() {\n    JavaFileObject source =\n        JavaFileObjects.forSourceLines(\n            \"test.ValidInRound2\",\n            \"package test;\",\n            \"\",\n            \"@\" + AnAnnotation.class.getCanonicalName(),\n            \"public class ValidInRound2 {\",\n            \"  ValidInRound1XYZ vir1xyz;\",\n            \"  @\" + AnAnnotation.class.getCanonicalName(),\n            \"  static class ValidInRound1 {}\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new MissingAnnotationProcessor()).compile(source);\n    assertThat(compilation).succeeded();\n    assertThat(compilation).generatedSourceFile(\"test.ValidInRound2XYZ\");\n  }\n\n  @Test\n  public void properlySkipsMissingAnnotations_passesValidAnnotationsToProcess() {\n    JavaFileObject source =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassA\",\n            \"package test;\",\n            \"\",\n            \"@\" + AnAnnotation.class.getCanonicalName(),\n            \"public class ClassA {\",\n            \"}\");\n    MissingAnnotationProcessor missingAnnotationProcessor = new MissingAnnotationProcessor();\n    assertThat(javac().withProcessors(missingAnnotationProcessor).compile(source)).succeeded();\n    assertThat(missingAnnotationProcessor.getElementsByAnnotation().keySet())\n        .containsExactly(AnAnnotation.class.getCanonicalName());\n    assertThat(missingAnnotationProcessor.getElementsByAnnotation().values()).hasSize(1);\n  }\n\n  @Test\n  public void reportsMissingType() {\n    JavaFileObject classAFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassA\",\n            \"package test;\",\n            \"\",\n            \"@\" + RequiresGeneratedCode.class.getCanonicalName(),\n            \"public class ClassA {\",\n            \"  SomeGeneratedClass bar;\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new RequiresGeneratedCodeProcessor()).compile(classAFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(RequiresGeneratedCodeProcessor.class.getCanonicalName())\n        .inFile(classAFileObject)\n        .onLineContaining(\"class ClassA\");\n  }\n\n  @Test\n  public void reportsMissingTypeSuppressedWhenOtherErrors() {\n    JavaFileObject classAFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.ClassA\",\n            \"package test;\",\n            \"\",\n            \"@\" + CauseError.class.getCanonicalName(),\n            \"public class ClassA {}\");\n    Compilation compilation =\n        javac().withProcessors(new CauseErrorProcessor()).compile(classAFileObject);\n    assertThat(compilation).hadErrorContaining(\"purposeful\");\n  }\n\n  @Test\n  public void processingStepAsStepAnnotationsNamesMatchClasses() {\n    Step step = BasicAnnotationProcessor.asStep(new MultiAnnotationProcessingStep());\n\n    assertThat(step.annotations())\n        .containsExactly(\n            AnAnnotation.class.getCanonicalName(), ReferencesAClass.class.getCanonicalName());\n  }\n\n  /**\n   * Tests that a {@link ProcessingStep} passed to {@link\n   * BasicAnnotationProcessor#asStep(ProcessingStep)} still gets passed the correct arguments to\n   * {@link Step#process(ImmutableSetMultimap)}.\n   */\n  @Test\n  public void processingStepAsStepProcessElementsMatchClasses() {\n    Elements elements = compilation.getElements();\n    String anAnnotationName = AnAnnotation.class.getCanonicalName();\n    String referencesAClassName = ReferencesAClass.class.getCanonicalName();\n    TypeElement anAnnotationElement = elements.getTypeElement(anAnnotationName);\n    TypeElement referencesAClassElement = elements.getTypeElement(referencesAClassName);\n    MultiAnnotationProcessingStep processingStep = new MultiAnnotationProcessingStep();\n\n    BasicAnnotationProcessor.asStep(processingStep)\n        .process(\n            ImmutableSetMultimap.of(\n                anAnnotationName,\n                anAnnotationElement,\n                referencesAClassName,\n                referencesAClassElement));\n\n    assertThat(processingStep.getElementsByAnnotation())\n        .containsExactly(\n            AnAnnotation.class,\n            anAnnotationElement,\n            ReferencesAClass.class,\n            referencesAClassElement);\n  }\n\n  private static void generateClass(Filer filer, String generatedClassName) {\n    PrintWriter writer = null;\n    try {\n      writer = new PrintWriter(filer.createSourceFile(\"test.\" + generatedClassName).openWriter());\n      writer.println(\"package test;\");\n      writer.println(\"public class \" + generatedClassName + \" {}\");\n    } catch (IOException e) {\n      throw new RuntimeException(e);\n    } finally {\n      if (writer != null) {\n        writer.close();\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "common/src/test/java/com/google/auto/common/GeneratedAnnotationsTest.java",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.auto.common;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static java.nio.charset.StandardCharsets.UTF_8;\nimport static java.util.Objects.requireNonNull;\nimport static org.junit.Assume.assumeTrue;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.reflect.Reflection;\nimport com.squareup.javapoet.JavaFile;\nimport com.squareup.javapoet.TypeSpec;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.UncheckedIOException;\nimport java.lang.reflect.InvocationHandler;\nimport java.lang.reflect.Method;\nimport java.net.URI;\nimport java.nio.file.Files;\nimport java.util.Objects;\nimport java.util.Set;\nimport javax.annotation.processing.AbstractProcessor;\nimport javax.annotation.processing.RoundEnvironment;\nimport javax.annotation.processing.SupportedAnnotationTypes;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.TypeElement;\nimport javax.tools.JavaCompiler;\nimport javax.tools.JavaCompiler.CompilationTask;\nimport javax.tools.JavaFileObject.Kind;\nimport javax.tools.SimpleJavaFileObject;\nimport javax.tools.StandardJavaFileManager;\nimport javax.tools.StandardLocation;\nimport javax.tools.ToolProvider;\nimport org.jspecify.annotations.Nullable;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.rules.TemporaryFolder;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/** {@link GeneratedAnnotations}Test */\n@RunWith(JUnit4.class)\npublic class GeneratedAnnotationsTest {\n\n  @Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder();\n\n  private static final String JAVAX_ANNOTATION_PROCESSING_GENERATED =\n      \"javax.annotation.processing.Generated\";\n  private static final String JAVAX_ANNOTATION_GENERATED = \"javax.annotation.Generated\";\n\n  /**\n   * A toy annotation processor for testing. Matches on all annotations, and unconditionally\n   * generates a source that uses {@code @Generated}.\n   */\n  @SupportedAnnotationTypes(\"*\")\n  public static class TestProcessor extends AbstractProcessor {\n\n    @Override\n    public SourceVersion getSupportedSourceVersion() {\n      return SourceVersion.latestSupported();\n    }\n\n    private boolean first = true;\n\n    @Override\n    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n      if (first) {\n        TypeSpec.Builder type = TypeSpec.classBuilder(\"G\");\n        GeneratedAnnotationSpecs.generatedAnnotationSpec(\n                processingEnv.getElementUtils(),\n                processingEnv.getSourceVersion(),\n                TestProcessor.class)\n            .ifPresent(type::addAnnotation);\n        JavaFile javaFile = JavaFile.builder(\"\", type.build()).build();\n        try {\n          javaFile.writeTo(processingEnv.getFiler());\n        } catch (IOException e) {\n          throw new UncheckedIOException(e);\n        }\n        first = false;\n      }\n      return false;\n    }\n  }\n\n  /**\n   * Run {@link TestProcessor} in a compilation with the given {@code options}, and prevent the\n   * compilation from accessing classes with the qualified names in {@code maskFromClasspath}.\n   */\n  private String runProcessor(ImmutableList<String> options, @Nullable String packageToMask)\n      throws IOException {\n    File tempDir = temporaryFolder.newFolder();\n    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();\n    StandardJavaFileManager standardFileManager =\n        compiler.getStandardFileManager(/* diagnosticListener= */ null, /* locale= */ null, UTF_8);\n    standardFileManager.setLocation(StandardLocation.CLASS_OUTPUT, ImmutableList.of(tempDir));\n    StandardJavaFileManager proxyFileManager =\n        Reflection.newProxy(\n            StandardJavaFileManager.class,\n            new FileManagerInvocationHandler(standardFileManager, packageToMask));\n    CompilationTask task =\n        compiler.getTask(\n            /* out= */ null,\n            proxyFileManager,\n            /* diagnosticListener= */ null,\n            options,\n            /* classes= */ null,\n            ImmutableList.of(\n                new SimpleJavaFileObject(URI.create(\"test\"), Kind.SOURCE) {\n                  @Override\n                  public CharSequence getCharContent(boolean ignoreEncodingErrors)\n                      throws IOException {\n                    return \"class Test {}\";\n                  }\n                }));\n    task.setProcessors(ImmutableList.of(new TestProcessor()));\n    assertThat(task.call()).isTrue();\n    return new String(Files.readAllBytes(tempDir.toPath().resolve(\"G.java\")), UTF_8);\n  }\n\n  /**\n   * Used to produce a {@link StandardJavaFileManager} where a certain package appears to have no\n   * classes. The results are exactly those from the proxied {@code StandardJavaFileManager} except\n   * for the {@link StandardJavaFileManager#list list} method when its {@code packageName} argument\n   * is the given package, in which case the result is an empty list.\n   *\n   * <p>We can't use {@link javax.tools.ForwardingJavaFileManager} because at least some JDK\n   * versions require the file manager to be a {@code StandardJavaFileManager} when the {@code\n   * --release} flag is given.\n   */\n  private static class FileManagerInvocationHandler implements InvocationHandler {\n    private final StandardJavaFileManager fileManager;\n    private final @Nullable String packageToMask;\n\n    FileManagerInvocationHandler(\n        StandardJavaFileManager fileManager, @Nullable String packageToMask) {\n      this.fileManager = fileManager;\n      this.packageToMask = packageToMask;\n    }\n\n    @Override\n    public Object invoke(Object proxy, Method method, @Nullable Object @Nullable [] args)\n        throws Throwable {\n      if (method.getName().equals(\"list\")) {\n        String packageName = (String) requireNonNull(args)[1];\n        if (Objects.equals(packageName, packageToMask)) {\n          return ImmutableList.of();\n        }\n      }\n      return method.invoke(fileManager, args);\n    }\n  }\n\n  @Test\n  public void source8() throws Exception {\n    // Post-JDK8, we need to use --release 8 in order to be able to see the javax.annotation\n    // package, which was deleted from the JDK in that release. On JDK8, there is no --release\n    // option, so we have to use -source 8 -target 8.\n    ImmutableList<String> options =\n        isJdk9OrLater()\n            ? ImmutableList.of(\"--release\", \"8\")\n            : ImmutableList.of(\"-source\", \"8\", \"-target\", \"8\");\n    String generated = runProcessor(options, null);\n    assertThat(generated).contains(JAVAX_ANNOTATION_GENERATED);\n    assertThat(generated).doesNotContain(JAVAX_ANNOTATION_PROCESSING_GENERATED);\n  }\n\n  @Test\n  public void source8_masked() throws Exception {\n    // It appears that the StandardJavaFileManager hack that removes a package does not work in\n    // conjunction with --release. This is probably a bug. What we find is that\n    // Elements.getTypeElement returns a value for javax.annotation.Generated even though\n    // javax.annotation is being masked. It doesn't seem to go through the StandardJavaFileManager\n    // interface to get it. So, we continue using the -source 8 -target 8 options. Those don't\n    // actually get the JDK8 API when running post-JDK8, so we end up testing what we want.\n    //\n    // An alternative would be to delete this test method. JDK8 always has\n    // javax.annotation.Generated so it isn't really meaningful to test it without.\n    ImmutableList<String> options = ImmutableList.of(\"-source\", \"8\", \"-target\", \"8\");\n    String generated = runProcessor(options, \"javax.annotation\");\n    assertThat(generated).doesNotContain(JAVAX_ANNOTATION_GENERATED);\n    assertThat(generated).doesNotContain(JAVAX_ANNOTATION_PROCESSING_GENERATED);\n  }\n\n  @Test\n  public void source9() throws Exception {\n    assumeTrue(isJdk9OrLater());\n    String generated = runProcessor(ImmutableList.of(\"-source\", \"9\", \"-target\", \"9\"), null);\n    assertThat(generated).doesNotContain(JAVAX_ANNOTATION_GENERATED);\n    assertThat(generated).contains(JAVAX_ANNOTATION_PROCESSING_GENERATED);\n  }\n\n  @Test\n  public void source9_masked() throws Exception {\n    assumeTrue(isJdk9OrLater());\n    String generated =\n        runProcessor(\n            ImmutableList.of(\"-source\", \"9\", \"-target\", \"9\"), \"javax.annotation.processing\");\n    assertThat(generated).doesNotContain(JAVAX_ANNOTATION_GENERATED);\n    assertThat(generated).doesNotContain(JAVAX_ANNOTATION_PROCESSING_GENERATED);\n  }\n\n  private static boolean isJdk9OrLater() {\n    return SourceVersion.latestSupported().compareTo(SourceVersion.RELEASE_8) > 0;\n  }\n}\n"
  },
  {
    "path": "common/src/test/java/com/google/auto/common/MoreElementsTest.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport static com.google.common.collect.Iterables.getOnlyElement;\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.common.truth.Truth.assertWithMessage;\nimport static java.util.Objects.requireNonNull;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertTrue;\nimport static org.junit.Assert.fail;\n\nimport com.google.common.base.Optional;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Sets;\nimport com.google.common.truth.Expect;\nimport com.google.testing.compile.CompilationRule;\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.util.AbstractList;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.NoSuchElementException;\nimport java.util.Set;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.Modifier;\nimport javax.lang.model.element.PackageElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.ElementFilter;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.Types;\nimport org.junit.Before;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic class MoreElementsTest {\n  @Rule public CompilationRule compilation = new CompilationRule();\n  @Rule public Expect expect = Expect.create();\n\n  private Elements elements;\n  private PackageElement javaLangPackageElement;\n  private TypeElement objectElement;\n  private TypeElement stringElement;\n\n  @Before\n  public void initializeTestElements() {\n    this.elements = compilation.getElements();\n    this.javaLangPackageElement = elements.getPackageElement(\"java.lang\");\n    this.objectElement = elements.getTypeElement(Object.class.getCanonicalName());\n    this.stringElement = elements.getTypeElement(String.class.getCanonicalName());\n  }\n\n  @Test\n  public void getPackage() {\n    assertThat(MoreElements.getPackage(stringElement)).isEqualTo(javaLangPackageElement);\n    for (Element childElement : stringElement.getEnclosedElements()) {\n      assertThat(MoreElements.getPackage(childElement)).isEqualTo(javaLangPackageElement);\n    }\n  }\n\n  @Test\n  public void asPackage() {\n    assertThat(MoreElements.asPackage(javaLangPackageElement)).isEqualTo(javaLangPackageElement);\n  }\n\n  @Test\n  public void asPackage_illegalArgument() {\n    try {\n      MoreElements.asPackage(stringElement);\n      fail();\n    } catch (IllegalArgumentException expected) {\n    }\n  }\n\n  @Test\n  public void asTypeElement() {\n    Element typeElement = elements.getTypeElement(String.class.getCanonicalName());\n    assertTrue(MoreElements.isType(typeElement));\n    assertThat(MoreElements.asType(typeElement)).isEqualTo(typeElement);\n  }\n\n  @Test\n  public void asTypeElement_notATypeElement() {\n    TypeElement typeElement = elements.getTypeElement(String.class.getCanonicalName());\n    for (ExecutableElement e : ElementFilter.methodsIn(typeElement.getEnclosedElements())) {\n      assertFalse(MoreElements.isType(e));\n      try {\n        MoreElements.asType(e);\n        fail();\n      } catch (IllegalArgumentException expected) {\n      }\n    }\n  }\n\n  @Test\n  public void asTypeParameterElement() {\n    Element typeParameterElement =\n        getOnlyElement(\n            compilation\n                .getElements()\n                .getTypeElement(List.class.getCanonicalName())\n                .getTypeParameters());\n    assertThat(MoreElements.asTypeParameter(typeParameterElement)).isEqualTo(typeParameterElement);\n  }\n\n  @Test\n  public void asTypeParameterElement_illegalArgument() {\n    try {\n      MoreElements.asTypeParameter(javaLangPackageElement);\n      fail();\n    } catch (IllegalArgumentException expected) {\n    }\n  }\n\n  @Test\n  public void asType() {\n    assertThat(MoreElements.asType(stringElement)).isEqualTo(stringElement);\n  }\n\n  @Test\n  public void asType_illegalArgument() {\n    assertFalse(MoreElements.isType(javaLangPackageElement));\n    try {\n      MoreElements.asType(javaLangPackageElement);\n      fail();\n    } catch (IllegalArgumentException expected) {\n    }\n  }\n\n  @Test\n  public void asVariable() {\n    for (Element variableElement : ElementFilter.fieldsIn(stringElement.getEnclosedElements())) {\n      assertThat(MoreElements.asVariable(variableElement)).isEqualTo(variableElement);\n    }\n  }\n\n  @Test\n  public void asVariable_illegalArgument() {\n    try {\n      MoreElements.asVariable(javaLangPackageElement);\n      fail();\n    } catch (IllegalArgumentException expected) {\n    }\n  }\n\n  @Test\n  public void asExecutable() {\n    for (Element methodElement : ElementFilter.methodsIn(stringElement.getEnclosedElements())) {\n      assertThat(MoreElements.asExecutable(methodElement)).isEqualTo(methodElement);\n    }\n    for (Element methodElement :\n        ElementFilter.constructorsIn(stringElement.getEnclosedElements())) {\n      assertThat(MoreElements.asExecutable(methodElement)).isEqualTo(methodElement);\n    }\n  }\n\n  @Test\n  public void asExecutable_illegalArgument() {\n    try {\n      MoreElements.asExecutable(javaLangPackageElement);\n      fail();\n    } catch (IllegalArgumentException expected) {\n    }\n  }\n\n  @Retention(RetentionPolicy.RUNTIME)\n  private @interface InnerAnnotation {}\n\n  @Documented\n  @InnerAnnotation\n  private @interface AnnotatedAnnotation {}\n\n  @Test\n  public void isAnnotationPresent() {\n    TypeElement annotatedAnnotationElement =\n        elements.getTypeElement(AnnotatedAnnotation.class.getCanonicalName());\n\n    // Test Class API\n    isAnnotationPresentAsserts(\n        MoreElements.isAnnotationPresent(annotatedAnnotationElement, Documented.class),\n        MoreElements.isAnnotationPresent(annotatedAnnotationElement, InnerAnnotation.class),\n        MoreElements.isAnnotationPresent(annotatedAnnotationElement, SuppressWarnings.class));\n\n    // Test String API\n    String documentedName = Documented.class.getCanonicalName();\n    String innerAnnotationName = InnerAnnotation.class.getCanonicalName();\n    String suppressWarningsName = SuppressWarnings.class.getCanonicalName();\n    isAnnotationPresentAsserts(\n        MoreElements.isAnnotationPresent(annotatedAnnotationElement, documentedName),\n        MoreElements.isAnnotationPresent(annotatedAnnotationElement, innerAnnotationName),\n        MoreElements.isAnnotationPresent(annotatedAnnotationElement, suppressWarningsName));\n\n    // Test TypeElement API\n    TypeElement documentedElement = elements.getTypeElement(documentedName);\n    TypeElement innerAnnotationElement = elements.getTypeElement(innerAnnotationName);\n    TypeElement suppressWarningsElement = elements.getTypeElement(suppressWarningsName);\n    isAnnotationPresentAsserts(\n        MoreElements.isAnnotationPresent(annotatedAnnotationElement, documentedElement),\n        MoreElements.isAnnotationPresent(annotatedAnnotationElement, innerAnnotationElement),\n        MoreElements.isAnnotationPresent(annotatedAnnotationElement, suppressWarningsElement));\n  }\n\n  private void isAnnotationPresentAsserts(\n      boolean isDocumentedPresent,\n      boolean isInnerAnnotationPresent,\n      boolean isSuppressWarningsPresent) {\n    assertThat(isDocumentedPresent).isTrue();\n    assertThat(isInnerAnnotationPresent).isTrue();\n    assertThat(isSuppressWarningsPresent).isFalse();\n  }\n\n  @Test\n  public void getAnnotationMirror() {\n    TypeElement element = elements.getTypeElement(AnnotatedAnnotation.class.getCanonicalName());\n\n    // Test Class API\n    getAnnotationMirrorAsserts(\n        MoreElements.getAnnotationMirror(element, Documented.class),\n        MoreElements.getAnnotationMirror(element, InnerAnnotation.class),\n        MoreElements.getAnnotationMirror(element, SuppressWarnings.class));\n\n    // Test String API\n    String documentedName = Documented.class.getCanonicalName();\n    String innerAnnotationName = InnerAnnotation.class.getCanonicalName();\n    String suppressWarningsName = SuppressWarnings.class.getCanonicalName();\n    getAnnotationMirrorAsserts(\n        MoreElements.getAnnotationMirror(element, documentedName),\n        MoreElements.getAnnotationMirror(element, innerAnnotationName),\n        MoreElements.getAnnotationMirror(element, suppressWarningsName));\n\n    // Test TypeElement API\n    TypeElement documentedElement = elements.getTypeElement(documentedName);\n    TypeElement innerAnnotationElement = elements.getTypeElement(innerAnnotationName);\n    TypeElement suppressWarningsElement = elements.getTypeElement(suppressWarningsName);\n    getAnnotationMirrorAsserts(\n        MoreElements.getAnnotationMirror(element, documentedElement),\n        MoreElements.getAnnotationMirror(element, innerAnnotationElement),\n        MoreElements.getAnnotationMirror(element, suppressWarningsElement));\n  }\n\n  private void getAnnotationMirrorAsserts(\n      Optional<AnnotationMirror> documented,\n      Optional<AnnotationMirror> innerAnnotation,\n      Optional<AnnotationMirror> suppressWarnings) {\n    expect.that(documented).isPresent();\n    expect.that(innerAnnotation).isPresent();\n    expect.that(suppressWarnings).isAbsent();\n\n    Element annotationElement = documented.get().getAnnotationType().asElement();\n    expect.that(MoreElements.isType(annotationElement)).isTrue();\n    expect\n        .that(MoreElements.asType(annotationElement).getQualifiedName().toString())\n        .isEqualTo(Documented.class.getCanonicalName());\n\n    annotationElement = innerAnnotation.get().getAnnotationType().asElement();\n    expect.that(MoreElements.isType(annotationElement)).isTrue();\n    expect\n        .that(MoreElements.asType(annotationElement).getQualifiedName().toString())\n        .isEqualTo(InnerAnnotation.class.getCanonicalName());\n  }\n\n  private abstract static class ParentClass {\n    static void staticMethod() {}\n\n    abstract String foo();\n\n    @SuppressWarnings(\"unused\")\n    private void privateMethod() {}\n  }\n\n  private interface ParentInterface {\n    static void staticMethod() {}\n\n    abstract int bar();\n\n    abstract int bar(long x);\n  }\n\n  private abstract static class Child extends ParentClass implements ParentInterface {\n    static void staticMethod() {}\n\n    @Override\n    public int bar() {\n      return 0;\n    }\n\n    abstract void baz();\n\n    void buh(int x) {}\n\n    void buh(int x, int y) {}\n  }\n\n  @Test\n  public void getLocalAndInheritedMethods_Old() {\n    Types types = compilation.getTypes();\n    TypeMirror intMirror = types.getPrimitiveType(TypeKind.INT);\n    TypeMirror longMirror = types.getPrimitiveType(TypeKind.LONG);\n    TypeElement childType = elements.getTypeElement(Child.class.getCanonicalName());\n    @SuppressWarnings(\"deprecation\")\n    Set<ExecutableElement> childTypeMethods =\n        MoreElements.getLocalAndInheritedMethods(childType, elements);\n    Set<ExecutableElement> objectMethods = visibleMethodsFromObject();\n    assertThat(childTypeMethods).containsAtLeastElementsIn(objectMethods);\n    Set<ExecutableElement> nonObjectMethods = Sets.difference(childTypeMethods, objectMethods);\n    assertThat(nonObjectMethods)\n        .containsExactly(\n            getMethod(ParentInterface.class, \"bar\", longMirror),\n            getMethod(ParentClass.class, \"foo\"),\n            getMethod(Child.class, \"bar\"),\n            getMethod(Child.class, \"baz\"),\n            getMethod(Child.class, \"buh\", intMirror),\n            getMethod(Child.class, \"buh\", intMirror, intMirror))\n        .inOrder();\n    ;\n  }\n\n  @Test\n  public void getLocalAndInheritedMethods() {\n    Types types = compilation.getTypes();\n    TypeMirror intMirror = types.getPrimitiveType(TypeKind.INT);\n    TypeMirror longMirror = types.getPrimitiveType(TypeKind.LONG);\n    TypeElement childType = elements.getTypeElement(Child.class.getCanonicalName());\n    @SuppressWarnings(\"deprecation\")\n    Set<ExecutableElement> childTypeMethods =\n        MoreElements.getLocalAndInheritedMethods(childType, types, elements);\n    Set<ExecutableElement> objectMethods = visibleMethodsFromObject();\n    assertThat(childTypeMethods).containsAtLeastElementsIn(objectMethods);\n    Set<ExecutableElement> nonObjectMethods = Sets.difference(childTypeMethods, objectMethods);\n    assertThat(nonObjectMethods)\n        .containsExactly(\n            getMethod(ParentInterface.class, \"bar\", longMirror),\n            getMethod(ParentClass.class, \"foo\"),\n            getMethod(Child.class, \"bar\"),\n            getMethod(Child.class, \"baz\"),\n            getMethod(Child.class, \"buh\", intMirror),\n            getMethod(Child.class, \"buh\", intMirror, intMirror))\n        .inOrder();\n  }\n\n  @Test\n  public void getLocalAndInheritedMethods_recursiveTypeVariableBound() {\n    Types types = compilation.getTypes();\n    TypeElement builderElement =\n        elements.getTypeElement(FakeProto.Builder.class.getCanonicalName());\n    TypeMirror abstractMessageLiteMirror =\n        elements.getTypeElement(AbstractMessageLite.class.getCanonicalName()).asType();\n    ExecutableElement internalMergeFromMethod =\n        getMethod(FakeProto.Builder.class, \"internalMergeFrom\", abstractMessageLiteMirror);\n\n    ImmutableSet<ExecutableElement> methods =\n        MoreElements.getLocalAndInheritedMethods(builderElement, types, elements);\n\n    assertThat(methods).contains(internalMergeFromMethod);\n  }\n\n  // The classes that follow mimic the proto classes that triggered the bug that\n  // getLocalAndInheritedMethods_recursiveTypeVariableBound is testing for. They include raw type\n  // usages, because the corresponding real proto API classes do.\n\n  static class FakeProto extends AbstractMessage {\n    static class Builder extends AbstractMessage.Builder<Builder> {\n      @Override\n      @SuppressWarnings(\"rawtypes\")\n      Builder internalMergeFrom(AbstractMessageLite other) {\n        return this;\n      }\n    }\n  }\n\n  @SuppressWarnings(\"rawtypes\")\n  static class AbstractMessage extends AbstractMessageLite {\n    static class Builder<B extends Builder<B>> extends AbstractMessageLite.Builder {\n      @Override\n      @SuppressWarnings(\"unchecked\")\n      B internalMergeFrom(AbstractMessageLite other) {\n        return (B) this;\n      }\n    }\n  }\n\n  static class AbstractMessageLite<\n      M extends AbstractMessageLite<M, B>, B extends AbstractMessageLite.Builder<M, B>> {\n    static class Builder<M extends AbstractMessageLite<M, B>, B extends Builder<M, B>> {\n      @SuppressWarnings(\"unchecked\")\n      B internalMergeFrom(M other) {\n        return (B) this;\n      }\n    }\n  }\n\n  @Test\n  public void getAllMethods() {\n    Types types = compilation.getTypes();\n    TypeMirror intMirror = types.getPrimitiveType(TypeKind.INT);\n    TypeMirror longMirror = types.getPrimitiveType(TypeKind.LONG);\n    TypeElement childType = elements.getTypeElement(Child.class.getCanonicalName());\n    @SuppressWarnings(\"deprecation\")\n    Set<ExecutableElement> childTypeMethods =\n        MoreElements.getAllMethods(childType, types, elements);\n    Set<ExecutableElement> objectMethods = allMethodsFromObject();\n    assertThat(childTypeMethods).containsAtLeastElementsIn(objectMethods);\n    Set<ExecutableElement> nonObjectMethods = Sets.difference(childTypeMethods, objectMethods);\n    assertThat(nonObjectMethods)\n        .containsExactly(\n            getMethod(ParentInterface.class, \"staticMethod\"),\n            getMethod(ParentInterface.class, \"bar\", longMirror),\n            getMethod(ParentClass.class, \"staticMethod\"),\n            getMethod(ParentClass.class, \"foo\"),\n            getMethod(ParentClass.class, \"privateMethod\"),\n            getMethod(Child.class, \"staticMethod\"),\n            getMethod(Child.class, \"bar\"),\n            getMethod(Child.class, \"baz\"),\n            getMethod(Child.class, \"buh\", intMirror),\n            getMethod(Child.class, \"buh\", intMirror, intMirror))\n        .inOrder();\n  }\n\n  private Set<ExecutableElement> visibleMethodsFromObject() {\n    Types types = compilation.getTypes();\n    TypeMirror intMirror = types.getPrimitiveType(TypeKind.INT);\n    TypeMirror longMirror = types.getPrimitiveType(TypeKind.LONG);\n    Set<ExecutableElement> methods = new HashSet<ExecutableElement>();\n    for (ExecutableElement method : ElementFilter.methodsIn(objectElement.getEnclosedElements())) {\n      if (method.getModifiers().contains(Modifier.PUBLIC)\n          || method.getModifiers().contains(Modifier.PROTECTED)) {\n        methods.add(method);\n      }\n    }\n    assertThat(methods)\n        .containsAtLeast(\n            getMethod(Object.class, \"clone\"),\n            getMethod(Object.class, \"finalize\"),\n            getMethod(Object.class, \"wait\"),\n            getMethod(Object.class, \"wait\", longMirror),\n            getMethod(Object.class, \"wait\", longMirror, intMirror));\n    return methods;\n  }\n\n  private Set<ExecutableElement> allMethodsFromObject() {\n    Types types = compilation.getTypes();\n    TypeMirror intMirror = types.getPrimitiveType(TypeKind.INT);\n    TypeMirror longMirror = types.getPrimitiveType(TypeKind.LONG);\n    Set<ExecutableElement> methods = new HashSet<>();\n    methods.addAll(ElementFilter.methodsIn(objectElement.getEnclosedElements()));\n    assertThat(methods)\n        .containsAtLeast(\n            getMethod(Object.class, \"clone\"),\n            getMethod(Object.class, \"finalize\"),\n            getMethod(Object.class, \"wait\"),\n            getMethod(Object.class, \"wait\", longMirror),\n            getMethod(Object.class, \"wait\", longMirror, intMirror));\n    return methods;\n  }\n\n  private ExecutableElement getMethod(Class<?> c, String methodName, TypeMirror... parameterTypes) {\n    TypeElement type = elements.getTypeElement(c.getCanonicalName());\n    Types types = compilation.getTypes();\n    ExecutableElement found = null;\n    for (ExecutableElement method : ElementFilter.methodsIn(type.getEnclosedElements())) {\n      if (method.getSimpleName().contentEquals(methodName)\n          && method.getParameters().size() == parameterTypes.length) {\n        boolean match = true;\n        for (int i = 0; i < parameterTypes.length; i++) {\n          TypeMirror expectedType = parameterTypes[i];\n          TypeMirror actualType = method.getParameters().get(i).asType();\n          match &= types.isSameType(types.erasure(expectedType), types.erasure(actualType));\n        }\n        if (match) {\n          assertThat(found).isNull();\n          found = method;\n        }\n      }\n    }\n    assertWithMessage(methodName + Arrays.toString(parameterTypes)).that(found).isNotNull();\n    return requireNonNull(found);\n  }\n\n  private abstract static class AbstractAbstractList extends AbstractList<String> {}\n\n  private static class ConcreteAbstractList<T> extends AbstractList<T> {\n    @Override\n    public int size() {\n      return 0;\n    }\n\n    @Override\n    public T get(int index) {\n      throw new NoSuchElementException();\n    }\n  }\n\n  private Set<String> abstractMethodNamesFrom(Set<ExecutableElement> methods) {\n    ImmutableSet.Builder<String> abstractMethodNames = ImmutableSet.builder();\n    for (ExecutableElement method : methods) {\n      if (method.getModifiers().contains(Modifier.ABSTRACT)) {\n        abstractMethodNames.add(method.getSimpleName().toString());\n      }\n    }\n    return abstractMethodNames.build();\n  }\n\n  // Test that getLocalAndInheritedMethods does the right thing with AbstractList. That class\n  // inherits from Collection along two paths, via its parent AbstractCollection (which implements\n  // Collection) and via its parent List (which extends Collection). Bugs in the past have meant\n  // that the multiple paths might lead the code into thinking that all the abstract methods of\n  // Collection were still abstract in the AbstractList subclasses here, even though most of them\n  // are implemented in AbstractList.\n  @Test\n  public void getLocalAndInheritedMethods_AbstractList() {\n    TypeElement abstractType =\n        elements.getTypeElement(AbstractAbstractList.class.getCanonicalName());\n    Set<ExecutableElement> abstractTypeMethods =\n        MoreElements.getLocalAndInheritedMethods(abstractType, elements);\n    assertThat(abstractMethodNamesFrom(abstractTypeMethods)).containsExactly(\"get\", \"size\");\n\n    TypeElement concreteType =\n        elements.getTypeElement(ConcreteAbstractList.class.getCanonicalName());\n    Set<ExecutableElement> concreteTypeMethods =\n        MoreElements.getLocalAndInheritedMethods(concreteType, elements);\n    assertThat(abstractMethodNamesFrom(concreteTypeMethods)).isEmpty();\n  }\n}\n"
  },
  {
    "path": "common/src/test/java/com/google/auto/common/MoreTypesIsTypeOfTest.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport static com.google.common.truth.Truth.assertWithMessage;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertTrue;\nimport static org.junit.Assert.fail;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.Iterables;\nimport com.google.testing.compile.CompilationRule;\nimport java.util.List;\nimport java.util.SortedMap;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.Types;\nimport org.junit.Before;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/** Tests {@link MoreTypes#isTypeOf(Class, TypeMirror)}. */\n@RunWith(JUnit4.class)\npublic class MoreTypesIsTypeOfTest {\n\n  @Rule public CompilationRule compilationRule = new CompilationRule();\n\n  private Elements elementUtils;\n  private Types typeUtils;\n\n  @Before\n  public void setUp() {\n    this.elementUtils = compilationRule.getElements();\n    this.typeUtils = compilationRule.getTypes();\n  }\n\n  @Test\n  public void isTypeOf_primitiveAndBoxedPrimitiveTypes() {\n    class PrimitiveTypeInfo {\n      final Class<?> CLASS_TYPE;\n      final Class<?> BOXED_CLASS_TYPE;\n      final TypeKind TYPE_KIND;\n\n      PrimitiveTypeInfo(Class<?> classType, Class<?> boxedClassType, TypeKind typeKind) {\n        this.CLASS_TYPE = classType;\n        this.BOXED_CLASS_TYPE = boxedClassType;\n        this.TYPE_KIND = typeKind;\n      }\n    }\n    final List<PrimitiveTypeInfo> primitivesTypeInfo =\n        ImmutableList.of(\n            new PrimitiveTypeInfo(Byte.TYPE, Byte.class, TypeKind.BYTE),\n            new PrimitiveTypeInfo(Short.TYPE, Short.class, TypeKind.SHORT),\n            new PrimitiveTypeInfo(Integer.TYPE, Integer.class, TypeKind.INT),\n            new PrimitiveTypeInfo(Long.TYPE, Long.class, TypeKind.LONG),\n            new PrimitiveTypeInfo(Float.TYPE, Float.class, TypeKind.FLOAT),\n            new PrimitiveTypeInfo(Double.TYPE, Double.class, TypeKind.DOUBLE),\n            new PrimitiveTypeInfo(Boolean.TYPE, Boolean.class, TypeKind.BOOLEAN),\n            new PrimitiveTypeInfo(Character.TYPE, Character.class, TypeKind.CHAR));\n\n    for (boolean isBoxedI : new boolean[] {false, true}) {\n      for (int i = 0; i < primitivesTypeInfo.size(); i++) { // For the Class<?> arg\n        Class<?> clazz =\n            isBoxedI\n                ? primitivesTypeInfo.get(i).BOXED_CLASS_TYPE\n                : primitivesTypeInfo.get(i).CLASS_TYPE;\n\n        for (boolean isBoxedJ : new boolean[] {false, true}) {\n          for (int j = 0; j < primitivesTypeInfo.size(); j++) { // For the TypeMirror arg\n            TypeKind typeKind = primitivesTypeInfo.get(j).TYPE_KIND;\n            TypeMirror typeMirror =\n                isBoxedJ\n                    ? typeUtils.boxedClass(typeUtils.getPrimitiveType(typeKind)).asType()\n                    : typeUtils.getPrimitiveType(typeKind);\n\n            String message =\n                \"Mirror:\\t\" + typeMirror.toString() + \"\\nClass:\\t\" + clazz.getCanonicalName();\n            if (isBoxedI == isBoxedJ && i == j) {\n              assertWithMessage(message).that(MoreTypes.isTypeOf(clazz, typeMirror)).isTrue();\n            } else {\n              assertWithMessage(message).that(MoreTypes.isTypeOf(clazz, typeMirror)).isFalse();\n            }\n          }\n        }\n      }\n    }\n  }\n\n  @Test\n  public void isTypeOf_voidAndPseudoVoidTypes() {\n    TypeMirror voidType = typeUtils.getNoType(TypeKind.VOID);\n    TypeMirror pseudoVoidType = getTypeElementFor(Void.class).asType();\n\n    assertWithMessage(\"Mirror:\\t\" + voidType + \"\\nClass:\\t\" + Void.TYPE.getCanonicalName())\n        .that(MoreTypes.isTypeOf(Void.TYPE, voidType))\n        .isTrue();\n    assertWithMessage(\"Mirror:\\t\" + pseudoVoidType + \"\\nClass:\\t\" + Void.TYPE.getCanonicalName())\n        .that(MoreTypes.isTypeOf(Void.TYPE, pseudoVoidType))\n        .isFalse();\n\n    assertWithMessage(\"Mirror:\\t\" + voidType + \"\\nClass:\\t\" + Void.class.getCanonicalName())\n        .that(MoreTypes.isTypeOf(Void.class, voidType))\n        .isFalse();\n    assertWithMessage(\"Mirror:\\t\" + pseudoVoidType + \"\\nClass:\\t\" + Void.class.getCanonicalName())\n        .that(MoreTypes.isTypeOf(Void.class, pseudoVoidType))\n        .isTrue();\n  }\n\n  @Test\n  public void isTypeOf_arrayType() {\n    TypeMirror type = typeUtils.getArrayType(getTypeElementFor(String.class).asType());\n    assertWithMessage(\"Mirror:\\t\" + type + \"\\nClass:\\t\" + String[].class.getCanonicalName())\n        .that(MoreTypes.isTypeOf(String[].class, type))\n        .isTrue();\n    assertWithMessage(\"Mirror:\\t\" + type + \"\\nClass:\\t\" + Integer[].class.getCanonicalName())\n        .that(MoreTypes.isTypeOf(Integer[].class, type))\n        .isFalse();\n    assertWithMessage(\"Mirror:\\t\" + type + \"\\nClass:\\t\" + int[].class.getCanonicalName())\n        .that(MoreTypes.isTypeOf(int[].class, type))\n        .isFalse();\n\n    type = typeUtils.getArrayType(typeUtils.getPrimitiveType(TypeKind.INT));\n    assertWithMessage(\"Mirror:\\t\" + type + \"\\nClass:\\t\" + String[].class.getCanonicalName())\n        .that(MoreTypes.isTypeOf(String[].class, type))\n        .isFalse();\n    assertWithMessage(\"Mirror:\\t\" + type + \"\\nClass:\\t\" + Integer[].class.getCanonicalName())\n        .that(MoreTypes.isTypeOf(Integer[].class, type))\n        .isFalse();\n    assertWithMessage(\"Mirror:\\t\" + type + \"\\nClass:\\t\" + int[].class.getCanonicalName())\n        .that(MoreTypes.isTypeOf(int[].class, type))\n        .isTrue();\n  }\n\n  private interface TestType {\n    @SuppressWarnings(\"unused\")\n    <T extends SortedMap<Number, String>> T method0();\n  }\n\n  @Test\n  public void isTypeOf_declaredType() {\n    TypeMirror TestTypeTypeMirror = getTypeElementFor(TestType.class).asType();\n    assertTrue(MoreTypes.isType(TestTypeTypeMirror));\n    assertWithMessage(\n            \"Mirror:\\t\" + TestTypeTypeMirror + \"\\nClass:\\t\" + TestType.class.getCanonicalName())\n        .that(MoreTypes.isTypeOf(TestType.class, TestTypeTypeMirror))\n        .isTrue();\n    assertWithMessage(\n            \"Mirror:\\t\" + TestTypeTypeMirror + \"\\nClass:\\t\" + String.class.getCanonicalName())\n        .that(MoreTypes.isTypeOf(String.class, TestTypeTypeMirror))\n        .isFalse();\n  }\n\n  @Test\n  public void isTypeOf_fail() {\n    TypeMirror methodType =\n        Iterables.getOnlyElement(getTypeElementFor(TestType.class).getEnclosedElements()).asType();\n    assertFalse(MoreTypes.isType(methodType));\n    try {\n      MoreTypes.isTypeOf(List.class, methodType);\n      fail();\n    } catch (IllegalArgumentException expected) {\n    }\n  }\n\n  /* Utility method(s) */\n  private TypeElement getTypeElementFor(Class<?> clazz) {\n    return elementUtils.getTypeElement(clazz.getCanonicalName());\n  }\n}\n"
  },
  {
    "path": "common/src/test/java/com/google/auto/common/MoreTypesTest.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static java.util.Objects.requireNonNull;\nimport static javax.lang.model.type.TypeKind.NONE;\nimport static javax.lang.model.type.TypeKind.VOID;\nimport static org.junit.Assert.assertThrows;\nimport static org.junit.Assert.fail;\n\nimport com.google.common.base.Optional;\nimport com.google.common.collect.FluentIterable;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Iterables;\nimport com.google.common.testing.EquivalenceTester;\nimport com.google.common.truth.Expect;\nimport com.google.testing.compile.CompilationRule;\nimport java.lang.annotation.Annotation;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.TypeParameterElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.ErrorType;\nimport javax.lang.model.type.PrimitiveType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.type.TypeVisitor;\nimport javax.lang.model.type.WildcardType;\nimport javax.lang.model.util.ElementFilter;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.Types;\nimport org.jspecify.annotations.Nullable;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic class MoreTypesTest {\n  @Rule public final CompilationRule compilationRule = new CompilationRule();\n  @Rule public final Expect expect = Expect.create();\n\n  @Test\n  public void equivalence() {\n    Types types = compilationRule.getTypes();\n    Elements elements = compilationRule.getElements();\n    TypeMirror objectType = elements.getTypeElement(Object.class.getCanonicalName()).asType();\n    TypeMirror stringType = elements.getTypeElement(String.class.getCanonicalName()).asType();\n    TypeElement mapElement = elements.getTypeElement(Map.class.getCanonicalName());\n    TypeElement setElement = elements.getTypeElement(Set.class.getCanonicalName());\n    TypeElement enumElement = elements.getTypeElement(Enum.class.getCanonicalName());\n    TypeElement container = elements.getTypeElement(Container.class.getCanonicalName());\n    TypeElement contained = elements.getTypeElement(Container.Contained.class.getCanonicalName());\n    TypeElement funkyBounds = elements.getTypeElement(FunkyBounds.class.getCanonicalName());\n    TypeElement funkyBounds2 = elements.getTypeElement(FunkyBounds2.class.getCanonicalName());\n    TypeElement funkierBounds = elements.getTypeElement(FunkierBounds.class.getCanonicalName());\n    TypeMirror funkyBoundsVar = ((DeclaredType) funkyBounds.asType()).getTypeArguments().get(0);\n    TypeMirror funkyBounds2Var = ((DeclaredType) funkyBounds2.asType()).getTypeArguments().get(0);\n    TypeMirror funkierBoundsVar = ((DeclaredType) funkierBounds.asType()).getTypeArguments().get(0);\n    DeclaredType mapOfObjectToObjectType =\n        types.getDeclaredType(mapElement, objectType, objectType);\n    TypeMirror mapType = mapElement.asType();\n    DeclaredType setOfSetOfObject =\n        types.getDeclaredType(setElement, types.getDeclaredType(setElement, objectType));\n    DeclaredType setOfSetOfString =\n        types.getDeclaredType(setElement, types.getDeclaredType(setElement, stringType));\n    DeclaredType setOfSetOfSetOfObject = types.getDeclaredType(setElement, setOfSetOfObject);\n    DeclaredType setOfSetOfSetOfString = types.getDeclaredType(setElement, setOfSetOfString);\n    WildcardType wildcard = types.getWildcardType(null, null);\n    DeclaredType containerOfObject = types.getDeclaredType(container, objectType);\n    DeclaredType containerOfString = types.getDeclaredType(container, stringType);\n    TypeMirror containedInObject = types.asMemberOf(containerOfObject, contained);\n    TypeMirror containedInString = types.asMemberOf(containerOfString, contained);\n    EquivalenceTester<TypeMirror> tester =\n        EquivalenceTester.<TypeMirror>of(MoreTypes.equivalence())\n            .addEquivalenceGroup(types.getNullType())\n            .addEquivalenceGroup(types.getNoType(NONE))\n            .addEquivalenceGroup(types.getNoType(VOID))\n            .addEquivalenceGroup(objectType)\n            .addEquivalenceGroup(stringType)\n            .addEquivalenceGroup(containedInObject)\n            .addEquivalenceGroup(containedInString)\n            .addEquivalenceGroup(funkyBounds.asType())\n            .addEquivalenceGroup(funkyBounds2.asType())\n            .addEquivalenceGroup(funkierBounds.asType())\n            .addEquivalenceGroup(funkyBoundsVar, funkyBounds2Var)\n            .addEquivalenceGroup(funkierBoundsVar)\n            // Enum<E extends Enum<E>>\n            .addEquivalenceGroup(enumElement.asType())\n            // Map<K, V>\n            .addEquivalenceGroup(mapType)\n            .addEquivalenceGroup(mapOfObjectToObjectType)\n            // Map<?, ?>\n            .addEquivalenceGroup(types.getDeclaredType(mapElement, wildcard, wildcard))\n            // Map\n            .addEquivalenceGroup(types.erasure(mapType), types.erasure(mapOfObjectToObjectType))\n            .addEquivalenceGroup(types.getDeclaredType(mapElement, objectType, stringType))\n            .addEquivalenceGroup(types.getDeclaredType(mapElement, stringType, objectType))\n            .addEquivalenceGroup(types.getDeclaredType(mapElement, stringType, stringType))\n            .addEquivalenceGroup(setOfSetOfObject)\n            .addEquivalenceGroup(setOfSetOfString)\n            .addEquivalenceGroup(setOfSetOfSetOfObject)\n            .addEquivalenceGroup(setOfSetOfSetOfString)\n            .addEquivalenceGroup(wildcard)\n            // ? extends Object\n            .addEquivalenceGroup(types.getWildcardType(objectType, null))\n            // ? extends String\n            .addEquivalenceGroup(types.getWildcardType(stringType, null))\n            // ? super String\n            .addEquivalenceGroup(types.getWildcardType(null, stringType))\n            // Map<String, Map<String, Set<Object>>>\n            .addEquivalenceGroup(\n                types.getDeclaredType(\n                    mapElement,\n                    stringType,\n                    types.getDeclaredType(\n                        mapElement, stringType, types.getDeclaredType(setElement, objectType))))\n            .addEquivalenceGroup(FAKE_ERROR_TYPE);\n\n    for (TypeKind kind : TypeKind.values()) {\n      if (kind.isPrimitive()) {\n        PrimitiveType primitiveType = types.getPrimitiveType(kind);\n        TypeMirror boxedPrimitiveType = types.boxedClass(primitiveType).asType();\n        tester.addEquivalenceGroup(primitiveType, types.unboxedType(boxedPrimitiveType));\n        tester.addEquivalenceGroup(boxedPrimitiveType);\n        tester.addEquivalenceGroup(types.getArrayType(primitiveType));\n        tester.addEquivalenceGroup(types.getArrayType(boxedPrimitiveType));\n      }\n    }\n\n    ImmutableSet<Class<?>> testClasses =\n        ImmutableSet.of(\n            ExecutableElementsGroupA.class,\n            ExecutableElementsGroupB.class,\n            ExecutableElementsGroupC.class,\n            ExecutableElementsGroupD.class,\n            ExecutableElementsGroupE.class);\n    for (Class<?> testClass : testClasses) {\n      ImmutableList<TypeMirror> equivalenceGroup =\n          FluentIterable.from(\n                  elements.getTypeElement(testClass.getCanonicalName()).getEnclosedElements())\n              .transform(Element::asType)\n              .toList();\n      tester.addEquivalenceGroup(equivalenceGroup);\n    }\n\n    tester.test();\n  }\n\n  @SuppressWarnings(\"unused\")\n  private static final class ExecutableElementsGroupA {\n    ExecutableElementsGroupA() {}\n\n    void a() {}\n\n    public static void b() {}\n  }\n\n  @SuppressWarnings(\"unused\")\n  private static final class ExecutableElementsGroupB {\n    ExecutableElementsGroupB(String s) {}\n\n    void a(String s) {}\n\n    public static void b(String s) {}\n  }\n\n  @SuppressWarnings(\"unused\")\n  private static final class ExecutableElementsGroupC {\n    ExecutableElementsGroupC() throws Exception {}\n\n    void a() throws Exception {}\n\n    public static void b() throws Exception {}\n  }\n\n  @SuppressWarnings(\"unused\")\n  private static final class ExecutableElementsGroupD {\n    ExecutableElementsGroupD() throws RuntimeException {}\n\n    void a() throws RuntimeException {}\n\n    public static void b() throws RuntimeException {}\n  }\n\n  @SuppressWarnings({\"unused\", \"UnusedTypeParameter\"})\n  private static final class ExecutableElementsGroupE {\n    <T> ExecutableElementsGroupE() {}\n\n    <T> void a() {}\n\n    public static <T> void b() {}\n  }\n\n  @SuppressWarnings({\"unused\", \"UnusedTypeParameter\"})\n  private static final class Container<T> {\n    private final class Contained {}\n  }\n\n  @SuppressWarnings(\"unused\")\n  private static final class FunkyBounds<T extends Number & Comparable<T>> {}\n\n  @SuppressWarnings(\"unused\")\n  private static final class FunkyBounds2<T extends Number & Comparable<T>> {}\n\n  @SuppressWarnings(\"unused\")\n  private static final class FunkierBounds<T extends Number & Comparable<T> & Cloneable> {}\n\n  @Test\n  public void testReferencedTypes() {\n    Elements elements = compilationRule.getElements();\n    TypeElement testDataElement =\n        elements.getTypeElement(ReferencedTypesTestData.class.getCanonicalName());\n    ImmutableMap<String, VariableElement> fieldIndex =\n        FluentIterable.from(ElementFilter.fieldsIn(testDataElement.getEnclosedElements()))\n            .uniqueIndex(input -> input.getSimpleName().toString());\n\n    TypeElement objectElement = elements.getTypeElement(Object.class.getCanonicalName());\n    TypeElement stringElement = elements.getTypeElement(String.class.getCanonicalName());\n    TypeElement integerElement = elements.getTypeElement(Integer.class.getCanonicalName());\n    TypeElement setElement = elements.getTypeElement(Set.class.getCanonicalName());\n    TypeElement mapElement = elements.getTypeElement(Map.class.getCanonicalName());\n    TypeElement charSequenceElement =\n        elements.getTypeElement(CharSequence.class.getCanonicalName());\n\n    assertThat(referencedTypes(fieldIndex, \"f1\")).containsExactly(objectElement);\n    assertThat(referencedTypes(fieldIndex, \"f2\")).containsExactly(setElement, stringElement);\n    assertThat(referencedTypes(fieldIndex, \"f3\"))\n        .containsExactly(mapElement, stringElement, objectElement);\n    assertThat(referencedTypes(fieldIndex, \"f4\")).containsExactly(integerElement);\n    assertThat(referencedTypes(fieldIndex, \"f5\")).containsExactly(setElement);\n    assertThat(referencedTypes(fieldIndex, \"f6\")).containsExactly(setElement, charSequenceElement);\n    assertThat(referencedTypes(fieldIndex, \"f7\"))\n        .containsExactly(mapElement, stringElement, setElement, charSequenceElement);\n    assertThat(referencedTypes(fieldIndex, \"f8\")).containsExactly(stringElement);\n    assertThat(referencedTypes(fieldIndex, \"f9\")).containsExactly(stringElement);\n    assertThat(referencedTypes(fieldIndex, \"f10\")).isEmpty();\n    assertThat(referencedTypes(fieldIndex, \"f11\")).isEmpty();\n    assertThat(referencedTypes(fieldIndex, \"f12\")).containsExactly(setElement, stringElement);\n  }\n\n  private static ImmutableSet<TypeElement> referencedTypes(\n      ImmutableMap<String, VariableElement> fieldIndex, String fieldName) {\n    VariableElement field = fieldIndex.get(fieldName);\n    requireNonNull(field, fieldName);\n    return MoreTypes.referencedTypes(field.asType());\n  }\n\n  @SuppressWarnings(\"unused\") // types used in compiler tests\n  private static final class ReferencedTypesTestData {\n    Object f1;\n    Set<String> f2;\n    Map<String, Object> f3;\n    Integer f4;\n    Set<?> f5;\n    Set<? extends CharSequence> f6;\n    Map<String, Set<? extends CharSequence>> f7;\n    String[] f8;\n    String[][] f9;\n    int f10;\n    int[] f11;\n    Set<? super String> f12;\n  }\n\n  private static class Parent<T> {}\n\n  private static class ChildA extends Parent<Number> {}\n\n  private static class ChildB extends Parent<String> {}\n\n  private static class GenericChild<T> extends Parent<T> {}\n\n  private interface InterfaceType {}\n\n  @Test\n  public void asElement_throws() {\n    TypeMirror javaDotLang = compilationRule.getElements().getPackageElement(\"java.lang\").asType();\n    try {\n      MoreTypes.asElement(javaDotLang);\n      fail();\n    } catch (IllegalArgumentException expected) {\n    }\n  }\n\n  @Test\n  public void asElement() {\n    Elements elements = compilationRule.getElements();\n    TypeElement stringElement = elements.getTypeElement(\"java.lang.String\");\n    assertThat(MoreTypes.asElement(stringElement.asType())).isEqualTo(stringElement);\n    TypeParameterElement setParameterElement =\n        Iterables.getOnlyElement(\n            compilationRule.getElements().getTypeElement(\"java.util.Set\").getTypeParameters());\n    assertThat(MoreTypes.asElement(setParameterElement.asType())).isEqualTo(setParameterElement);\n    // we don't test error types because those are very hard to get predictably\n  }\n\n  @Test\n  public void testNonObjectSuperclass() {\n    Types types = compilationRule.getTypes();\n    Elements elements = compilationRule.getElements();\n    TypeMirror numberType = elements.getTypeElement(Number.class.getCanonicalName()).asType();\n    TypeMirror stringType = elements.getTypeElement(String.class.getCanonicalName()).asType();\n    TypeMirror integerType = elements.getTypeElement(Integer.class.getCanonicalName()).asType();\n    TypeElement parent = elements.getTypeElement(Parent.class.getCanonicalName());\n    TypeElement childA = elements.getTypeElement(ChildA.class.getCanonicalName());\n    TypeElement childB = elements.getTypeElement(ChildB.class.getCanonicalName());\n    TypeElement genericChild = elements.getTypeElement(GenericChild.class.getCanonicalName());\n    TypeMirror genericChildOfNumber = types.getDeclaredType(genericChild, numberType);\n    TypeMirror genericChildOfInteger = types.getDeclaredType(genericChild, integerType);\n    TypeMirror objectType = elements.getTypeElement(Object.class.getCanonicalName()).asType();\n    TypeMirror interfaceType =\n        elements.getTypeElement(InterfaceType.class.getCanonicalName()).asType();\n\n    assertThat(MoreTypes.nonObjectSuperclass(types, elements, (DeclaredType) objectType))\n        .isAbsent();\n    assertThat(MoreTypes.nonObjectSuperclass(types, elements, (DeclaredType) interfaceType))\n        .isAbsent();\n    assertThat(MoreTypes.nonObjectSuperclass(types, elements, (DeclaredType) parent.asType()))\n        .isAbsent();\n\n    Optional<DeclaredType> parentOfChildA =\n        MoreTypes.nonObjectSuperclass(types, elements, (DeclaredType) childA.asType());\n    Optional<DeclaredType> parentOfChildB =\n        MoreTypes.nonObjectSuperclass(types, elements, (DeclaredType) childB.asType());\n    Optional<DeclaredType> parentOfGenericChild =\n        MoreTypes.nonObjectSuperclass(types, elements, (DeclaredType) genericChild.asType());\n    Optional<DeclaredType> parentOfGenericChildOfNumber =\n        MoreTypes.nonObjectSuperclass(types, elements, (DeclaredType) genericChildOfNumber);\n    Optional<DeclaredType> parentOfGenericChildOfInteger =\n        MoreTypes.nonObjectSuperclass(types, elements, (DeclaredType) genericChildOfInteger);\n\n    EquivalenceTester<TypeMirror> tester =\n        EquivalenceTester.<TypeMirror>of(MoreTypes.equivalence())\n            .addEquivalenceGroup(\n                parentOfChildA.get(),\n                types.getDeclaredType(parent, numberType),\n                parentOfGenericChildOfNumber.get())\n            .addEquivalenceGroup(parentOfChildB.get(), types.getDeclaredType(parent, stringType))\n            .addEquivalenceGroup(parentOfGenericChild.get(), parent.asType())\n            .addEquivalenceGroup(\n                parentOfGenericChildOfInteger.get(), types.getDeclaredType(parent, integerType));\n\n    tester.test();\n  }\n\n  @Test\n  public void testAsMemberOf_variableElement() {\n    Types types = compilationRule.getTypes();\n    Elements elements = compilationRule.getElements();\n    TypeMirror numberType = elements.getTypeElement(Number.class.getCanonicalName()).asType();\n    TypeMirror stringType = elements.getTypeElement(String.class.getCanonicalName()).asType();\n    TypeMirror integerType = elements.getTypeElement(Integer.class.getCanonicalName()).asType();\n\n    TypeElement paramsElement = elements.getTypeElement(Params.class.getCanonicalName());\n    VariableElement tParam =\n        Iterables.getOnlyElement(\n            Iterables.getOnlyElement(ElementFilter.methodsIn(paramsElement.getEnclosedElements()))\n                .getParameters());\n    VariableElement tField =\n        Iterables.getOnlyElement(ElementFilter.fieldsIn(paramsElement.getEnclosedElements()));\n\n    DeclaredType numberParams =\n        (DeclaredType) elements.getTypeElement(NumberParams.class.getCanonicalName()).asType();\n    DeclaredType stringParams =\n        (DeclaredType) elements.getTypeElement(StringParams.class.getCanonicalName()).asType();\n    TypeElement genericParams = elements.getTypeElement(GenericParams.class.getCanonicalName());\n    DeclaredType genericParamsOfNumber = types.getDeclaredType(genericParams, numberType);\n    DeclaredType genericParamsOfInteger = types.getDeclaredType(genericParams, integerType);\n\n    TypeMirror fieldOfNumberParams = MoreTypes.asMemberOf(types, numberParams, tField);\n    TypeMirror paramOfNumberParams = MoreTypes.asMemberOf(types, numberParams, tParam);\n    TypeMirror fieldOfStringParams = MoreTypes.asMemberOf(types, stringParams, tField);\n    TypeMirror paramOfStringParams = MoreTypes.asMemberOf(types, stringParams, tParam);\n    TypeMirror fieldOfGenericOfNumber = MoreTypes.asMemberOf(types, genericParamsOfNumber, tField);\n    TypeMirror paramOfGenericOfNumber = MoreTypes.asMemberOf(types, genericParamsOfNumber, tParam);\n    TypeMirror fieldOfGenericOfInteger =\n        MoreTypes.asMemberOf(types, genericParamsOfInteger, tField);\n    TypeMirror paramOfGenericOfInteger =\n        MoreTypes.asMemberOf(types, genericParamsOfInteger, tParam);\n\n    EquivalenceTester<TypeMirror> tester =\n        EquivalenceTester.<TypeMirror>of(MoreTypes.equivalence())\n            .addEquivalenceGroup(\n                fieldOfNumberParams,\n                paramOfNumberParams,\n                fieldOfGenericOfNumber,\n                paramOfGenericOfNumber,\n                numberType)\n            .addEquivalenceGroup(fieldOfStringParams, paramOfStringParams, stringType)\n            .addEquivalenceGroup(fieldOfGenericOfInteger, paramOfGenericOfInteger, integerType);\n    tester.test();\n  }\n\n  private static class Params<T> {\n    @SuppressWarnings(\"unused\")\n    T t;\n\n    @SuppressWarnings(\"unused\")\n    void add(T t) {}\n  }\n\n  private static class NumberParams extends Params<Number> {}\n\n  private static class StringParams extends Params<String> {}\n\n  private static class GenericParams<T> extends Params<T> {}\n\n  private static final ErrorType FAKE_ERROR_TYPE =\n      new ErrorType() {\n        @Override\n        public TypeKind getKind() {\n          return TypeKind.ERROR;\n        }\n\n        @Override\n        public <R, P> R accept(TypeVisitor<R, P> v, P p) {\n          return v.visitError(this, p);\n        }\n\n        @Override\n        public ImmutableList<? extends TypeMirror> getTypeArguments() {\n          return ImmutableList.of();\n        }\n\n        @Override\n        public @Nullable TypeMirror getEnclosingType() {\n          return null;\n        }\n\n        @Override\n        public @Nullable Element asElement() {\n          return null;\n        }\n\n        @Override\n        public <A extends Annotation> A @Nullable [] getAnnotationsByType(Class<A> annotationType) {\n          return null;\n        }\n\n        @Override\n        public <A extends Annotation> @Nullable A getAnnotation(Class<A> annotationType) {\n          return null;\n        }\n\n        @Override\n        @SuppressWarnings(\"MutableMethodReturnType\")\n        public List<? extends AnnotationMirror> getAnnotationMirrors() {\n          return ImmutableList.of();\n        }\n      };\n\n  @Test\n  public void testIsConversionFromObjectUnchecked_yes() {\n    Elements elements = compilationRule.getElements();\n    TypeElement unchecked = elements.getTypeElement(Unchecked.class.getCanonicalName());\n    for (VariableElement field : ElementFilter.fieldsIn(unchecked.getEnclosedElements())) {\n      TypeMirror type = field.asType();\n      expect\n          .withMessage(\"Casting to %s is unchecked\", type)\n          .that(MoreTypes.isConversionFromObjectUnchecked(type))\n          .isTrue();\n    }\n  }\n\n  @Test\n  public void testIsConversionFromObjectUnchecked_no() {\n    Elements elements = compilationRule.getElements();\n    TypeElement notUnchecked = elements.getTypeElement(NotUnchecked.class.getCanonicalName());\n    for (VariableElement field : ElementFilter.fieldsIn(notUnchecked.getEnclosedElements())) {\n      TypeMirror type = field.asType();\n      expect\n          .withMessage(\"Casting to %s is not unchecked\", type)\n          .that(MoreTypes.isConversionFromObjectUnchecked(type))\n          .isFalse();\n    }\n  }\n\n  @Test\n  public void testIsTypeOf() {\n    Types types = compilationRule.getTypes();\n    PrimitiveType intType = types.getPrimitiveType(TypeKind.INT);\n    TypeMirror integerType = types.boxedClass(intType).asType();\n    WildcardType wildcardType = types.getWildcardType(null, null);\n    expect.that(MoreTypes.isTypeOf(int.class, intType)).isTrue();\n    expect.that(MoreTypes.isTypeOf(Integer.class, integerType)).isTrue();\n    expect.that(MoreTypes.isTypeOf(Integer.class, intType)).isFalse();\n    expect.that(MoreTypes.isTypeOf(int.class, integerType)).isFalse();\n    expect.that(MoreTypes.isTypeOf(Integer.class, FAKE_ERROR_TYPE)).isFalse();\n    assertThrows(\n        IllegalArgumentException.class, () -> MoreTypes.isTypeOf(Integer.class, wildcardType));\n  }\n\n  // The type of every field here is such that casting to it provokes an \"unchecked\" warning.\n  @SuppressWarnings(\"unused\")\n  private static class Unchecked<T> {\n    private List<String> listOfString;\n    private List<? extends CharSequence> listOfExtendsCharSequence;\n    private List<? super CharSequence> listOfSuperCharSequence;\n    private List<T> listOfT;\n    private List<T[]> listOfArrayOfT;\n    private T t;\n    private T[] arrayOfT;\n    private List<T>[] arrayOfListOfT;\n    private Map<?, String> mapWildcardToString;\n    private Map<String, ?> mapStringToWildcard;\n  }\n\n  // The type of every field here is such that casting to it doesn't provoke an \"unchecked\" warning.\n  @SuppressWarnings(\"unused\")\n  private static class NotUnchecked {\n    private String string;\n    private int integer;\n    private String[] arrayOfString;\n    private int[] arrayOfInt;\n    private Thread.State threadStateEnum;\n    private List<?> listOfWildcard;\n    private List<? extends Object> listOfWildcardExtendsObject;\n    private Map<?, ?> mapWildcardToWildcard;\n  }\n}\n"
  },
  {
    "path": "common/src/test/java/com/google/auto/common/OverridesTest.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static java.nio.charset.StandardCharsets.UTF_8;\nimport static java.util.Objects.requireNonNull;\nimport static javax.lang.model.util.ElementFilter.methodsIn;\n\nimport com.google.common.base.Converter;\nimport com.google.common.base.Optional;\nimport com.google.common.base.StandardSystemProperty;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Range;\nimport com.google.common.io.Files;\nimport com.google.common.truth.Correspondence;\nimport com.google.common.truth.Expect;\nimport com.google.testing.compile.CompilationRule;\nimport java.io.File;\nimport java.util.AbstractCollection;\nimport java.util.AbstractList;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Set;\nimport javax.annotation.processing.AbstractProcessor;\nimport javax.annotation.processing.RoundEnvironment;\nimport javax.annotation.processing.SupportedAnnotationTypes;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.ArrayType;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.type.TypeVariable;\nimport javax.lang.model.type.TypeVisitor;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.SimpleTypeVisitor6;\nimport javax.lang.model.util.Types;\nimport javax.tools.JavaCompiler;\nimport javax.tools.JavaFileObject;\nimport javax.tools.StandardJavaFileManager;\nimport javax.tools.StandardLocation;\nimport org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;\nimport org.jspecify.annotations.Nullable;\nimport org.junit.Before;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.rules.TestRule;\nimport org.junit.runner.Description;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.Parameterized;\nimport org.junit.runners.model.Statement;\n\n/**\n * Tests that the {@link Overrides} class has behaviour consistent with javac. We test this in two\n * ways: once with {@link Overrides.ExplicitOverrides} using javac's own {@link Elements} and {@link\n * Types}, and once with it using the version of those objects from the Eclipse compiler (ecj).\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(Parameterized.class)\npublic class OverridesTest {\n  @Parameterized.Parameters(name = \"{0}\")\n  public static CompilerType[] data() {\n    return CompilerType.values();\n  }\n\n  @Rule public CompilationRule compilation = new CompilationRule();\n  @Rule public EcjCompilationRule ecjCompilation = new EcjCompilationRule();\n  @Rule public Expect expect = Expect.create();\n\n  public enum CompilerType {\n    JAVAC {\n      @Override\n      void initUtils(OverridesTest test) {\n        test.typeUtils = test.compilation.getTypes();\n        test.elementUtils = test.compilation.getElements();\n      }\n    },\n    ECJ {\n      @Override\n      void initUtils(OverridesTest test) {\n        test.typeUtils = test.ecjCompilation.types;\n        test.elementUtils = test.ecjCompilation.elements;\n      }\n    };\n\n    abstract void initUtils(OverridesTest test);\n  }\n\n  private final CompilerType compilerType;\n\n  private Types typeUtils;\n  private Elements elementUtils;\n  private Elements javacElementUtils;\n  private Overrides javacOverrides;\n  private Overrides.ExplicitOverrides explicitOverrides;\n\n  public OverridesTest(CompilerType compilerType) {\n    this.compilerType = compilerType;\n  }\n\n  @Before\n  public void initializeTestElements() {\n    javacElementUtils = compilation.getElements();\n    javacOverrides = new Overrides.NativeOverrides(javacElementUtils);\n    compilerType.initUtils(this);\n    explicitOverrides = new Overrides.ExplicitOverrides(typeUtils);\n  }\n\n  static class TypesForInheritance {\n    interface One {\n      void m();\n\n      void m(String x);\n\n      void n();\n\n      Number number();\n    }\n\n    interface Two {\n      void m();\n\n      void m(int x);\n\n      Integer number();\n    }\n\n    static class Parent {\n      public void m() {}\n    }\n\n    static class ChildOfParent extends Parent {}\n\n    static class ChildOfOne implements One {\n      @Override\n      public void m() {}\n\n      @Override\n      public void m(String x) {}\n\n      @Override\n      public void n() {}\n\n      @Override\n      public Number number() {\n        return 0;\n      }\n    }\n\n    static class ChildOfOneAndTwo implements One, Two {\n      @Override\n      public void m() {}\n\n      @Override\n      public void m(String x) {}\n\n      @Override\n      public void m(int x) {}\n\n      @Override\n      public void n() {}\n\n      @Override\n      public Integer number() {\n        return 0;\n      }\n    }\n\n    static class ChildOfParentAndOne extends Parent implements One {\n      @Override\n      public void m() {}\n\n      @Override\n      public void m(String x) {}\n\n      @Override\n      public void n() {}\n\n      @Override\n      public Number number() {\n        return 0;\n      }\n    }\n\n    static class ChildOfParentAndOneAndTwo extends Parent implements One, Two {\n      @Override\n      public void m(String x) {}\n\n      @Override\n      public void m(int x) {}\n\n      @Override\n      public void n() {}\n\n      @Override\n      public Integer number() {\n        return 0;\n      }\n    }\n\n    abstract static class AbstractChildOfOne implements One {}\n\n    abstract static class AbstractChildOfOneAndTwo implements One, Two {}\n\n    abstract static class AbstractChildOfParentAndOneAndTwo extends Parent implements One, Two {}\n\n    interface ExtendingOneAndTwo extends One, Two {}\n  }\n\n  static class MoreTypesForInheritance {\n    interface Key {}\n\n    interface BindingType {}\n\n    interface ContributionType {}\n\n    interface HasKey {\n      Key key();\n    }\n\n    interface HasBindingType {\n      BindingType bindingType();\n    }\n\n    interface HasContributionType {\n      ContributionType contributionType();\n    }\n\n    abstract static class BindingDeclaration implements HasKey {\n      abstract Optional<Element> bindingElement();\n\n      abstract Optional<TypeElement> contributingModule();\n    }\n\n    abstract static class MultibindingDeclaration extends BindingDeclaration\n        implements HasBindingType, HasContributionType {\n      @Override\n      public abstract Key key();\n\n      @Override\n      public abstract ContributionType contributionType();\n\n      @Override\n      public abstract BindingType bindingType();\n    }\n  }\n\n  static class TypesForVisibility {\n    public abstract static class PublicGrandparent {\n      public abstract String foo();\n    }\n\n    private static class PrivateParent extends PublicGrandparent {\n      @Override\n      public String foo() {\n        return \"foo\";\n      }\n    }\n\n    static class Child extends PrivateParent {}\n  }\n\n  static class TypesForGenerics {\n    interface GCollection<E> {\n      boolean add(E x);\n    }\n\n    interface GList<E> extends GCollection<E> {\n      @Override\n      boolean add(E x);\n    }\n\n    static class StringList implements GList<String> {\n      @Override\n      public boolean add(String x) {\n        return false;\n      }\n    }\n\n    @SuppressWarnings(\"rawtypes\")\n    static class RawList implements GList {\n      @Override\n      public boolean add(Object x) {\n        return false;\n      }\n    }\n  }\n\n  @SuppressWarnings(\"rawtypes\")\n  static class TypesForRaw {\n    static class RawParent {\n      void frob(List x) {}\n    }\n\n    static class RawChildOfRaw extends RawParent {\n      @Override\n      void frob(List x) {}\n    }\n\n    static class NonRawParent {\n      void frob(List<String> x) {}\n    }\n\n    static class RawChildOfNonRaw extends NonRawParent {\n      @Override\n      void frob(List x) {}\n    }\n  }\n\n  @Test\n  public void overridesInheritance() {\n    checkOverridesInContainedClasses(TypesForInheritance.class);\n  }\n\n  @Test\n  public void overridesMoreInheritance() {\n    checkOverridesInContainedClasses(MoreTypesForInheritance.class);\n  }\n\n  @Test\n  public void overridesVisibility() {\n    checkOverridesInContainedClasses(TypesForVisibility.class);\n  }\n\n  @Test\n  public void overridesGenerics() {\n    checkOverridesInContainedClasses(TypesForGenerics.class);\n  }\n\n  @Test\n  public void overridesRaw() {\n    checkOverridesInContainedClasses(TypesForRaw.class);\n  }\n\n  // Test a tricky diamond inheritance hierarchy:\n  //               Collection\n  //              /          \\\n  // AbstractCollection     List\n  //              \\          /\n  //              AbstractList\n  // This also tests that we do the right thing with generics, since naively the TypeMirror\n  // that you get for List<E> will not appear to be a subtype of the one you get for Collection<E>\n  // since the two Es are not the same.\n  @Test\n  public void overridesDiamond() {\n    checkOverridesInSet(\n        ImmutableSet.<Class<?>>of(\n            Collection.class, List.class, AbstractCollection.class, AbstractList.class));\n  }\n\n  private void checkOverridesInContainedClasses(Class<?> container) {\n    checkOverridesInSet(ImmutableSet.copyOf(container.getDeclaredClasses()));\n  }\n\n  private void checkOverridesInSet(ImmutableSet<Class<?>> testClasses) {\n    assertThat(testClasses).isNotEmpty();\n    ImmutableSet.Builder<TypeElement> testTypesBuilder = ImmutableSet.builder();\n    for (Class<?> testClass : testClasses) {\n      testTypesBuilder.add(getTypeElement(testClass));\n    }\n    ImmutableSet<TypeElement> testTypes = testTypesBuilder.build();\n    ImmutableSet.Builder<ExecutableElement> testMethodsBuilder = ImmutableSet.builder();\n    for (TypeElement testType : testTypes) {\n      testMethodsBuilder.addAll(methodsIn(testType.getEnclosedElements()));\n    }\n    ImmutableSet<ExecutableElement> testMethods = testMethodsBuilder.build();\n    for (TypeElement in : testTypes) {\n      TypeElement javacIn = javacType(in);\n      List<ExecutableElement> inMethods = methodsIn(elementUtils.getAllMembers(in));\n      for (ExecutableElement overrider : inMethods) {\n        ExecutableElement javacOverrider = javacMethod(overrider);\n        for (ExecutableElement overridden : testMethods) {\n          ExecutableElement javacOverridden = javacMethod(overridden);\n          boolean javacSays = javacOverrides.overrides(javacOverrider, javacOverridden, javacIn);\n          boolean weSay = explicitOverrides.overrides(overrider, overridden, in);\n          if (javacSays != weSay) {\n            expect\n                .withMessage(\n                    \"%s.%s overrides %s.%s in %s: javac says %s, we say %s\",\n                    overrider.getEnclosingElement(),\n                    overrider,\n                    overridden.getEnclosingElement(),\n                    overridden,\n                    in,\n                    javacSays,\n                    weSay)\n                .fail();\n          }\n        }\n      }\n    }\n  }\n\n  private TypeElement getTypeElement(Class<?> c) {\n    return elementUtils.getTypeElement(c.getCanonicalName());\n  }\n\n  private ExecutableElement getMethod(TypeElement in, String name, TypeKind... parameterTypeKinds) {\n    ExecutableElement found = null;\n    methods:\n    for (ExecutableElement method : methodsIn(in.getEnclosedElements())) {\n      if (method.getSimpleName().contentEquals(name)\n          && method.getParameters().size() == parameterTypeKinds.length) {\n        for (int i = 0; i < parameterTypeKinds.length; i++) {\n          if (method.getParameters().get(i).asType().getKind() != parameterTypeKinds[i]) {\n            continue methods;\n          }\n        }\n        assertThat(found).isNull();\n        found = method;\n      }\n    }\n    assertThat(found).isNotNull();\n    return requireNonNull(found);\n  }\n\n  // These skeletal parallels to the real collection classes ensure that the test is independent\n  // of the details of those classes, for example whether List<E> redeclares add(E) even though\n  // it also inherits it from Collection<E>.\n\n  private interface XCollection<E> {\n    @SuppressWarnings(\"unused\")\n    boolean add(E e);\n  }\n\n  private interface XList<E> extends XCollection<E> {}\n\n  private abstract static class XAbstractCollection<E> implements XCollection<E> {\n    @Override\n    public boolean add(E e) {\n      return false;\n    }\n  }\n\n  private abstract static class XAbstractList<E> extends XAbstractCollection<E>\n      implements XList<E> {\n    @Override\n    public boolean add(E e) {\n      return true;\n    }\n  }\n\n  private abstract static class XStringList extends XAbstractList<String> {}\n\n  private abstract static class XAbstractStringList implements XList<String> {}\n\n  private abstract static class XNumberList<E extends Number> extends XAbstractList<E> {}\n\n  // Parameter of add(E) in StringList is String.\n  // That means that we successfully recorded E[AbstractList] = String and E[List] = E[AbstractList]\n  // and String made it all the way through.\n  @Test\n  public void methodParameters_StringList() {\n    TypeElement xAbstractList = getTypeElement(XAbstractList.class);\n    TypeElement xStringList = getTypeElement(XStringList.class);\n    TypeElement string = getTypeElement(String.class);\n\n    ExecutableElement add = getMethod(xAbstractList, \"add\", TypeKind.TYPEVAR);\n    List<TypeMirror> params = explicitOverrides.erasedParameterTypes(add, xStringList);\n    List<TypeMirror> expectedParams = ImmutableList.of(string.asType());\n    assertTypeListsEqual(params, expectedParams);\n  }\n\n  // Parameter of add(E) in AbstractStringList is String.\n  // That means that we successfully recorded E[List] = String and E[Collection] = E[List].\n  @Test\n  public void methodParameters_AbstractStringList() {\n    TypeElement xCollection = getTypeElement(XCollection.class);\n    TypeElement xAbstractStringList = getTypeElement(XAbstractStringList.class);\n    TypeElement string = getTypeElement(String.class);\n\n    ExecutableElement add = getMethod(xCollection, \"add\", TypeKind.TYPEVAR);\n\n    List<TypeMirror> params = explicitOverrides.erasedParameterTypes(add, xAbstractStringList);\n    List<TypeMirror> expectedParams = ImmutableList.of(string.asType());\n    assertTypeListsEqual(params, expectedParams);\n  }\n\n  // Parameter of add(E) in NumberList is Number.\n  // That means that we successfully recorded E[AbstractList] = Number and on from\n  // there, with Number being used because it is the erasure of <E extends Number>.\n  @Test\n  public void methodParams_NumberList() {\n    TypeElement xCollection = getTypeElement(XCollection.class);\n    TypeElement xNumberList = getTypeElement(XNumberList.class);\n    TypeElement number = getTypeElement(Number.class);\n\n    ExecutableElement add = getMethod(xCollection, \"add\", TypeKind.TYPEVAR);\n\n    List<TypeMirror> params = explicitOverrides.erasedParameterTypes(add, xNumberList);\n    List<TypeMirror> expectedParams = ImmutableList.of(number.asType());\n    assertTypeListsEqual(params, expectedParams);\n  }\n\n  // This is derived from a class that provoked a StackOverflowError in an earlier version.\n  private abstract static class StringToRangeConverter<T extends Comparable<T>>\n      extends Converter<String, Range<T>> {\n    @Override\n    protected String doBackward(Range<T> b) {\n      return \"\";\n    }\n  }\n\n  @Test\n  public void methodParams_RecursiveBound() {\n    TypeElement stringToRangeConverter = getTypeElement(StringToRangeConverter.class);\n    TypeElement range = getTypeElement(Range.class);\n    ExecutableElement valueConverter =\n        getMethod(stringToRangeConverter, \"doBackward\", TypeKind.DECLARED);\n    List<TypeMirror> params =\n        explicitOverrides.erasedParameterTypes(valueConverter, stringToRangeConverter);\n    List<TypeMirror> expectedParams =\n        ImmutableList.<TypeMirror>of(typeUtils.erasure(range.asType()));\n    assertTypeListsEqual(params, expectedParams);\n  }\n\n  @Test\n  public void methodFromSuperclasses() {\n    TypeElement xAbstractCollection = getTypeElement(XAbstractCollection.class);\n    TypeElement xAbstractList = getTypeElement(XAbstractList.class);\n    TypeElement xAbstractStringList = getTypeElement(XAbstractStringList.class);\n    TypeElement xStringList = getTypeElement(XStringList.class);\n\n    ExecutableElement add = getMethod(xAbstractCollection, \"add\", TypeKind.TYPEVAR);\n\n    ExecutableElement addInAbstractStringList =\n        explicitOverrides.methodFromSuperclasses(xAbstractStringList, add);\n    assertThat(addInAbstractStringList).isNull();\n\n    ExecutableElement addInStringList = explicitOverrides.methodFromSuperclasses(xStringList, add);\n    assertThat(requireNonNull(addInStringList).getEnclosingElement()).isEqualTo(xAbstractList);\n  }\n\n  @Test\n  public void methodFromSuperinterfaces() {\n    TypeElement xCollection = getTypeElement(XCollection.class);\n    TypeElement xAbstractList = getTypeElement(XAbstractList.class);\n    TypeElement xAbstractStringList = getTypeElement(XAbstractStringList.class);\n    TypeElement xNumberList = getTypeElement(XNumberList.class);\n    TypeElement xList = getTypeElement(XList.class);\n\n    ExecutableElement add = getMethod(xCollection, \"add\", TypeKind.TYPEVAR);\n\n    ExecutableElement addInAbstractStringList =\n        explicitOverrides.methodFromSuperinterfaces(xAbstractStringList, add);\n    assertThat(requireNonNull(addInAbstractStringList).getEnclosingElement())\n        .isEqualTo(xCollection);\n\n    ExecutableElement addInNumberList =\n        explicitOverrides.methodFromSuperinterfaces(xNumberList, add);\n    assertThat(requireNonNull(addInNumberList).getEnclosingElement()).isEqualTo(xAbstractList);\n\n    ExecutableElement addInList = explicitOverrides.methodFromSuperinterfaces(xList, add);\n    assertThat(requireNonNull(addInList).getEnclosingElement()).isEqualTo(xCollection);\n  }\n\n  private void assertTypeListsEqual(@Nullable List<TypeMirror> actual, List<TypeMirror> expected) {\n    assertThat(actual)\n        .comparingElementsUsing(Correspondence.from(typeUtils::isSameType, \"is same type as\"))\n        .containsExactlyElementsIn(expected)\n        .inOrder();\n  }\n\n  // TODO(emcmanus): replace this with something from compile-testing when that's available.\n  /**\n   * An equivalent to {@link CompilationRule} that uses ecj (the Eclipse compiler) instead of javac.\n   * If the parameterized test is not selecting ecj then this rule has no effect.\n   */\n  public class EcjCompilationRule implements TestRule {\n    Elements elements;\n    Types types;\n\n    @Override\n    public Statement apply(Statement base, Description description) {\n      if (!compilerType.equals(CompilerType.ECJ)) {\n        return base;\n      }\n      return new EcjCompilationStatement(base);\n    }\n  }\n\n  private class EcjCompilationStatement extends Statement {\n    private final Statement statement;\n\n    EcjCompilationStatement(Statement base) {\n      this.statement = base;\n    }\n\n    @Override\n    public void evaluate() throws Throwable {\n      File tmpDir = File.createTempFile(\"OverridesTest\", \"dir\");\n      tmpDir.delete();\n      tmpDir.mkdir();\n      File dummySourceFile = new File(tmpDir, \"Dummy.java\");\n      try {\n        Files.asCharSink(dummySourceFile, UTF_8).write(\"class Dummy {}\");\n        evaluate(dummySourceFile);\n      } finally {\n        dummySourceFile.delete();\n        tmpDir.delete();\n      }\n    }\n\n    private void evaluate(File dummySourceFile) throws Throwable {\n      JavaCompiler compiler = new EclipseCompiler();\n      StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, UTF_8);\n      // This hack is only needed in a Google-internal Java 8 environment where symbolic links make\n      // it hard for ecj to find the boot class path. Elsewhere it is unnecessary but harmless.\n      File rtJar = new File(StandardSystemProperty.JAVA_HOME.value() + \"/lib/rt.jar\");\n      if (rtJar.exists()) {\n        List<File> bootClassPath =\n            ImmutableList.<File>builder()\n                .add(rtJar)\n                .addAll(fileManager.getLocation(StandardLocation.PLATFORM_CLASS_PATH))\n                .build();\n        fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, bootClassPath);\n      }\n      Iterable<? extends JavaFileObject> sources = fileManager.getJavaFileObjects(dummySourceFile);\n      JavaCompiler.CompilationTask task =\n          compiler.getTask(null, fileManager, null, null, null, sources);\n      EcjTestProcessor processor = new EcjTestProcessor(statement);\n      task.setProcessors(ImmutableList.of(processor));\n      assertThat(task.call()).isTrue();\n      processor.maybeThrow();\n    }\n  }\n\n  @SupportedAnnotationTypes(\"*\")\n  private class EcjTestProcessor extends AbstractProcessor {\n    private final Statement statement;\n    private Throwable thrown;\n\n    EcjTestProcessor(Statement statement) {\n      this.statement = statement;\n    }\n\n    @Override\n    public SourceVersion getSupportedSourceVersion() {\n      return SourceVersion.latest();\n    }\n\n    @Override\n    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n      if (roundEnv.processingOver()) {\n        ecjCompilation.elements = processingEnv.getElementUtils();\n        ecjCompilation.types = processingEnv.getTypeUtils();\n        try {\n          statement.evaluate();\n        } catch (Throwable t) {\n          thrown = t;\n        }\n      }\n      return false;\n    }\n\n    void maybeThrow() throws Throwable {\n      if (thrown != null) {\n        throw thrown;\n      }\n    }\n  }\n\n  private TypeElement javacType(TypeElement type) {\n    return javacElementUtils.getTypeElement(type.getQualifiedName().toString());\n  }\n\n  private ExecutableElement javacMethod(ExecutableElement method) {\n    if (elementUtils == javacElementUtils) {\n      return method;\n    }\n    TypeElement containingType = MoreElements.asType(method.getEnclosingElement());\n    TypeElement javacContainingType = javacType(containingType);\n    List<ExecutableElement> candidates = new ArrayList<ExecutableElement>();\n    methods:\n    for (ExecutableElement javacMethod : methodsIn(javacContainingType.getEnclosedElements())) {\n      if (javacMethod.getSimpleName().contentEquals(method.getSimpleName())\n          && javacMethod.getParameters().size() == method.getParameters().size()) {\n        for (int i = 0; i < method.getParameters().size(); i++) {\n          VariableElement parameter = method.getParameters().get(i);\n          VariableElement javacParameter = javacMethod.getParameters().get(i);\n          if (!erasedToString(parameter.asType()).equals(erasedToString(javacParameter.asType()))) {\n            continue methods;\n          }\n        }\n        candidates.add(javacMethod);\n      }\n    }\n    if (candidates.size() == 1) {\n      return candidates.get(0);\n    } else {\n      throw new IllegalStateException(\n          \"Expected one javac method matching \" + method + \" but found \" + candidates);\n    }\n  }\n\n  private static String erasedToString(TypeMirror type) {\n    return ERASED_STRING_TYPE_VISITOR.visit(type);\n  }\n\n  private static final TypeVisitor<String, Void> ERASED_STRING_TYPE_VISITOR =\n      new SimpleTypeVisitor6<String, Void>() {\n        @Override\n        protected String defaultAction(TypeMirror e, Void p) {\n          return e.toString();\n        }\n\n        @Override\n        public String visitArray(ArrayType t, Void p) {\n          return visit(t.getComponentType()) + \"[]\";\n        }\n\n        @Override\n        public String visitDeclared(DeclaredType t, Void p) {\n          return MoreElements.asType(t.asElement()).getQualifiedName().toString();\n        }\n\n        @Override\n        public String visitTypeVariable(TypeVariable t, Void p) {\n          return visit(t.getUpperBound());\n        }\n      };\n}\n"
  },
  {
    "path": "common/src/test/java/com/google/auto/common/SimpleAnnotationMirrorTest.java",
    "content": "/*\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.auto.common;\n\nimport static com.google.common.collect.Iterables.getOnlyElement;\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.fail;\n\nimport com.google.common.collect.ImmutableMap;\nimport com.google.testing.compile.CompilationRule;\nimport java.util.HashMap;\nimport java.util.Map;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.AnnotationValueVisitor;\nimport javax.lang.model.element.TypeElement;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/** Tests for {@link SimpleAnnotationMirror}. */\n@RunWith(JUnit4.class)\npublic class SimpleAnnotationMirrorTest {\n  @Rule public final CompilationRule compilation = new CompilationRule();\n\n  @interface EmptyAnnotation {}\n\n  @interface AnnotationWithDefault {\n    int value() default 3;\n  }\n\n  @interface MultipleValues {\n    int value1();\n\n    int value2();\n  }\n\n  @Test\n  public void emptyAnnotation() {\n    TypeElement emptyAnnotation = getTypeElement(EmptyAnnotation.class);\n    AnnotationMirror simpleAnnotation = SimpleAnnotationMirror.of(emptyAnnotation);\n    assertThat(simpleAnnotation.getAnnotationType()).isEqualTo(emptyAnnotation.asType());\n    assertThat(simpleAnnotation.getElementValues()).isEmpty();\n  }\n\n  @Test\n  public void multipleValues() {\n    TypeElement multipleValues = getTypeElement(MultipleValues.class);\n    Map<String, AnnotationValue> values = new HashMap<>();\n    values.put(\"value1\", intValue(1));\n    values.put(\"value2\", intValue(2));\n    assertThat(SimpleAnnotationMirror.of(multipleValues, values).getElementValues()).hasSize(2);\n  }\n\n  @Test\n  public void extraValues() {\n    TypeElement multipleValues = getTypeElement(MultipleValues.class);\n    Map<String, AnnotationValue> values = new HashMap<>();\n    values.put(\"value1\", intValue(1));\n    values.put(\"value2\", intValue(2));\n    values.put(\"value3\", intValue(3));\n    expectThrows(() -> SimpleAnnotationMirror.of(multipleValues, values));\n  }\n\n  @Test\n  public void defaultValue() {\n    TypeElement withDefaults = getTypeElement(AnnotationWithDefault.class);\n    AnnotationMirror annotation = SimpleAnnotationMirror.of(withDefaults);\n    assertThat(annotation.getElementValues()).hasSize(1);\n    assertThat(getOnlyElement(annotation.getElementValues().values()).getValue()).isEqualTo(3);\n  }\n\n  @Test\n  public void overriddenDefaultValue() {\n    TypeElement withDefaults = getTypeElement(AnnotationWithDefault.class);\n    AnnotationMirror annotation =\n        SimpleAnnotationMirror.of(withDefaults, ImmutableMap.of(\"value\", intValue(4)));\n    assertThat(annotation.getElementValues()).hasSize(1);\n    assertThat(getOnlyElement(annotation.getElementValues().values()).getValue()).isEqualTo(4);\n  }\n\n  @Test\n  public void missingValues() {\n    TypeElement multipleValues = getTypeElement(MultipleValues.class);\n    expectThrows(() -> SimpleAnnotationMirror.of(multipleValues));\n  }\n\n  @Test\n  public void notAnAnnotation() {\n    TypeElement stringElement = getTypeElement(String.class);\n    expectThrows(() -> SimpleAnnotationMirror.of(stringElement));\n  }\n\n  private TypeElement getTypeElement(Class<?> clazz) {\n    return compilation.getElements().getTypeElement(clazz.getCanonicalName());\n  }\n\n  private static void expectThrows(Runnable throwingRunnable) {\n    try {\n      throwingRunnable.run();\n      fail(\"Expected an IllegalArgumentException\");\n    } catch (IllegalArgumentException expected) {\n    }\n  }\n\n  private static AnnotationValue intValue(int value) {\n    return new AnnotationValue() {\n      @Override\n      public Object getValue() {\n        return value;\n      }\n\n      @Override\n      public <R, P> R accept(AnnotationValueVisitor<R, P> annotationValueVisitor, P p) {\n        return annotationValueVisitor.visitInt(value, p);\n      }\n    };\n  }\n}\n"
  },
  {
    "path": "common/src/test/java/com/google/auto/common/SimpleTypeAnnotationValueTest.java",
    "content": "/*\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.auto.common;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.fail;\n\nimport com.google.testing.compile.CompilationRule;\nimport java.util.List;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.type.PrimitiveType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.SimpleAnnotationValueVisitor8;\nimport javax.lang.model.util.Types;\nimport org.jspecify.annotations.Nullable;\nimport org.junit.Before;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/** Tests for {@link SimpleTypeAnnotationValue}. */\n@RunWith(JUnit4.class)\npublic class SimpleTypeAnnotationValueTest {\n  @Rule public final CompilationRule compilation = new CompilationRule();\n  private Types types;\n  private Elements elements;\n  private TypeMirror objectType;\n  private PrimitiveType primitiveType;\n\n  @Before\n  public void setUp() {\n    types = compilation.getTypes();\n    elements = compilation.getElements();\n    objectType = elements.getTypeElement(Object.class.getCanonicalName()).asType();\n    primitiveType = types.getPrimitiveType(TypeKind.BOOLEAN);\n  }\n\n  @Test\n  public void primitiveClass() {\n    AnnotationValue annotationValue = SimpleTypeAnnotationValue.of(primitiveType);\n    assertThat(annotationValue.getValue()).isEqualTo(primitiveType);\n  }\n\n  @Test\n  public void arrays() {\n    SimpleTypeAnnotationValue.of(types.getArrayType(objectType));\n    SimpleTypeAnnotationValue.of(types.getArrayType(primitiveType));\n  }\n\n  @Test\n  public void declaredType() {\n    SimpleTypeAnnotationValue.of(objectType);\n  }\n\n  @Test\n  public void visitorMethod() {\n    SimpleTypeAnnotationValue.of(objectType)\n        .accept(\n            new SimpleAnnotationValueVisitor8<@Nullable Void, @Nullable Void>() {\n              @Override\n              public @Nullable Void visitType(TypeMirror typeMirror, @Nullable Void aVoid) {\n                // do nothing, expected case\n                return null;\n              }\n\n              @Override\n              protected @Nullable Void defaultAction(Object o, @Nullable Void aVoid) {\n                throw new AssertionError();\n              }\n            },\n            null);\n  }\n\n  @Test\n  public void parameterizedType() {\n    try {\n      SimpleTypeAnnotationValue.of(\n          types.getDeclaredType(\n              elements.getTypeElement(List.class.getCanonicalName()), objectType));\n      fail(\"Expected an exception\");\n    } catch (IllegalArgumentException expected) {\n    }\n  }\n}\n"
  },
  {
    "path": "common/src/test/java/com/google/auto/common/SuperficialValidationTest.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.common.truth.Truth.assertWithMessage;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\nimport com.google.common.collect.ImmutableSet;\nimport com.google.testing.compile.JavaFileObjects;\nimport java.util.Set;\nimport java.util.function.Consumer;\nimport javax.annotation.processing.AbstractProcessor;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.annotation.processing.RoundEnvironment;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.TypeElement;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic class SuperficialValidationTest {\n  @Test\n  public void missingReturnType() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.TestClass\",\n            \"package test;\",\n            \"\",\n            \"abstract class TestClass {\",\n            \"  abstract MissingType blah();\",\n            \"}\");\n    assertAbout(javaSource())\n        .that(javaFileObject)\n        .processedWith(\n            new AssertingProcessor(\n                processingEnv -> {\n                  TypeElement testClassElement =\n                      processingEnv.getElementUtils().getTypeElement(\"test.TestClass\");\n                  assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();\n                }))\n        .failsToCompile();\n  }\n\n  @Test\n  public void missingGenericReturnType() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.TestClass\",\n            \"package test;\",\n            \"\",\n            \"abstract class TestClass {\",\n            \"  abstract MissingType<?> blah();\",\n            \"}\");\n    assertAbout(javaSource())\n        .that(javaFileObject)\n        .processedWith(\n            new AssertingProcessor(\n                processingEnv -> {\n                  TypeElement testClassElement =\n                      processingEnv.getElementUtils().getTypeElement(\"test.TestClass\");\n                  assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();\n                }))\n        .failsToCompile();\n  }\n\n  @Test\n  public void missingReturnTypeTypeParameter() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.TestClass\",\n            \"package test;\",\n            \"\",\n            \"import java.util.Map;\",\n            \"import java.util.Set;\",\n            \"\",\n            \"abstract class TestClass {\",\n            \"  abstract Map<Set<?>, MissingType<?>> blah();\",\n            \"}\");\n    assertAbout(javaSource())\n        .that(javaFileObject)\n        .processedWith(\n            new AssertingProcessor(\n                processingEnv -> {\n                  TypeElement testClassElement =\n                      processingEnv.getElementUtils().getTypeElement(\"test.TestClass\");\n                  assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();\n                }))\n        .failsToCompile();\n  }\n\n  @Test\n  public void missingTypeParameter() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.TestClass\", //\n            \"package test;\",\n            \"\",\n            \"class TestClass<T extends MissingType> {}\");\n    assertAbout(javaSource())\n        .that(javaFileObject)\n        .processedWith(\n            new AssertingProcessor(\n                processingEnv -> {\n                  TypeElement testClassElement =\n                      processingEnv.getElementUtils().getTypeElement(\"test.TestClass\");\n                  assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();\n                }))\n        .failsToCompile();\n  }\n\n  @Test\n  public void missingParameterType() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.TestClass\",\n            \"package test;\",\n            \"\",\n            \"abstract class TestClass {\",\n            \"  abstract void foo(MissingType x);\",\n            \"}\");\n    assertAbout(javaSource())\n        .that(javaFileObject)\n        .processedWith(\n            new AssertingProcessor(\n                processingEnv -> {\n                  TypeElement testClassElement =\n                      processingEnv.getElementUtils().getTypeElement(\"test.TestClass\");\n                  assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();\n                }))\n        .failsToCompile();\n  }\n\n  @Test\n  public void missingAnnotation() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.TestClass\", //\n            \"package test;\",\n            \"\",\n            \"@MissingAnnotation\",\n            \"class TestClass {}\");\n    assertAbout(javaSource())\n        .that(javaFileObject)\n        .processedWith(\n            new AssertingProcessor(\n                processingEnv -> {\n                  TypeElement testClassElement =\n                      processingEnv.getElementUtils().getTypeElement(\"test.TestClass\");\n                  // It appears that in some JDK versions, getAnnotationMirrors() doesn't return\n                  // erroneous annotations such as we have here.\n                  if (!testClassElement.getAnnotationMirrors().isEmpty()) {\n                    assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();\n                  }\n                }))\n        .failsToCompile();\n  }\n\n  @Test\n  public void handlesRecursiveTypeParams() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.TestClass\", //\n            \"package test;\",\n            \"\",\n            \"class TestClass<T extends Comparable<T>> {}\");\n    assertAbout(javaSource())\n        .that(javaFileObject)\n        .processedWith(\n            new AssertingProcessor(\n                processingEnv -> {\n                  TypeElement testClassElement =\n                      processingEnv.getElementUtils().getTypeElement(\"test.TestClass\");\n                  assertThat(SuperficialValidation.validateElement(testClassElement)).isTrue();\n                }))\n        .compilesWithoutError();\n  }\n\n  @Test\n  public void handlesRecursiveType() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.TestClass\",\n            \"package test;\",\n            \"\",\n            \"abstract class TestClass {\",\n            \"  abstract TestClass foo(TestClass x);\",\n            \"}\");\n    assertAbout(javaSource())\n        .that(javaFileObject)\n        .processedWith(\n            new AssertingProcessor(\n                processingEnv -> {\n                  TypeElement testClassElement =\n                      processingEnv.getElementUtils().getTypeElement(\"test.TestClass\");\n                  assertThat(SuperficialValidation.validateElement(testClassElement)).isTrue();\n                }))\n        .compilesWithoutError();\n  }\n\n  @Test\n  public void missingWildcardBound() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.TestClass\",\n            \"package test;\",\n            \"\",\n            \"import java.util.Set;\",\n            \"\",\n            \"class TestClass {\",\n            \"  Set<? extends MissingType> extendsTest() {\",\n            \"    return null;\",\n            \"  }\",\n            \"\",\n            \"  Set<? super MissingType> superTest() {\",\n            \"    return null;\",\n            \"  }\",\n            \"}\");\n    assertAbout(javaSource())\n        .that(javaFileObject)\n        .processedWith(\n            new AssertingProcessor(\n                processingEnv -> {\n                  TypeElement testClassElement =\n                      processingEnv.getElementUtils().getTypeElement(\"test.TestClass\");\n                  assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();\n                }))\n        .failsToCompile();\n  }\n\n  @Test\n  public void missingIntersection() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.TestClass\",\n            \"package test;\",\n            \"\",\n            \"class TestClass<T extends Number & Missing> {}\");\n    assertAbout(javaSource())\n        .that(javaFileObject)\n        .processedWith(\n            new AssertingProcessor(\n                processingEnv -> {\n                  TypeElement testClassElement =\n                      processingEnv.getElementUtils().getTypeElement(\"test.TestClass\");\n                  assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();\n                }))\n        .failsToCompile();\n  }\n\n  @Test\n  public void invalidAnnotationValue() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"test.Outer\",\n            \"package test;\",\n            \"\",\n            \"final class Outer {\",\n            \"  @interface TestAnnotation {\",\n            \"    Class[] classes();\",\n            \"  }\",\n            \"\",\n            \"  @TestAnnotation(classes = Foo)\",\n            \"  static class TestClass {}\",\n            \"}\");\n    assertAbout(javaSource())\n        .that(javaFileObject)\n        .processedWith(\n            new AssertingProcessor(\n                processingEnv -> {\n                  TypeElement testClassElement =\n                      processingEnv.getElementUtils().getTypeElement(\"test.Outer.TestClass\");\n                  assertWithMessage(\"testClassElement is valid\")\n                      .that(SuperficialValidation.validateElement(testClassElement))\n                      .isFalse();\n                }))\n        .failsToCompile();\n  }\n\n  private static class AssertingProcessor extends AbstractProcessor {\n\n    @Override\n    public SourceVersion getSupportedSourceVersion() {\n      return SourceVersion.latestSupported();\n    }\n\n    private final Consumer<ProcessingEnvironment> assertions;\n\n    AssertingProcessor(Consumer<ProcessingEnvironment> assertions) {\n      this.assertions = assertions;\n    }\n\n    @Override\n    public Set<String> getSupportedAnnotationTypes() {\n      return ImmutableSet.of(\"*\");\n    }\n\n    @Override\n    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n      assertions.accept(processingEnv);\n      return false;\n    }\n  }\n}\n"
  },
  {
    "path": "common/src/test/java/com/google/auto/common/VisibilityTest.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.common;\n\nimport static com.google.auto.common.Visibility.DEFAULT;\nimport static com.google.auto.common.Visibility.PRIVATE;\nimport static com.google.auto.common.Visibility.PROTECTED;\nimport static com.google.auto.common.Visibility.PUBLIC;\nimport static com.google.common.truth.Truth.assertThat;\n\nimport com.google.testing.compile.CompilationRule;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.util.Elements;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic class VisibilityTest {\n  @Rule public CompilationRule compilation = new CompilationRule();\n\n  @Test\n  public void packageVisibility() {\n    assertThat(Visibility.ofElement(compilation.getElements().getPackageElement(\"java.lang\")))\n        .isEqualTo(PUBLIC);\n    assertThat(\n            Visibility.ofElement(\n                compilation.getElements().getPackageElement(\"com.google.auto.common\")))\n        .isEqualTo(PUBLIC);\n  }\n\n  @Test\n  public void moduleVisibility() throws IllegalAccessException, InvocationTargetException {\n    Method getModuleElement;\n    try {\n      getModuleElement = Elements.class.getMethod(\"getModuleElement\", CharSequence.class);\n    } catch (NoSuchMethodException e) {\n      // TODO(ronshapiro): rewrite this test without reflection once we're on Java 9\n      return;\n    }\n    Element moduleElement =\n        (Element) getModuleElement.invoke(compilation.getElements(), \"java.base\");\n    assertThat(Visibility.ofElement(moduleElement)).isEqualTo(PUBLIC);\n  }\n\n  @SuppressWarnings(\"unused\")\n  public static class PublicClass {\n    public static class NestedPublicClass {}\n\n    protected static class NestedProtectedClass {}\n\n    static class NestedDefaultClass {}\n\n    private static class NestedPrivateClass {}\n  }\n\n  @SuppressWarnings(\"unused\")\n  protected static class ProtectedClass {\n    public static class NestedPublicClass {}\n\n    protected static class NestedProtectedClass {}\n\n    static class NestedDefaultClass {}\n\n    private static class NestedPrivateClass {}\n  }\n\n  @SuppressWarnings(\"unused\")\n  static class DefaultClass {\n    public static class NestedPublicClass {}\n\n    protected static class NestedProtectedClass {}\n\n    static class NestedDefaultClass {}\n\n    private static class NestedPrivateClass {}\n  }\n\n  @SuppressWarnings(\"unused\")\n  private static class PrivateClass {\n    public static class NestedPublicClass {}\n\n    protected static class NestedProtectedClass {}\n\n    static class NestedDefaultClass {}\n\n    private static class NestedPrivateClass {}\n  }\n\n  @Test\n  public void classVisibility() {\n    assertThat(Visibility.ofElement(compilation.getElements().getTypeElement(\"java.util.Map\")))\n        .isEqualTo(PUBLIC);\n    assertThat(\n            Visibility.ofElement(compilation.getElements().getTypeElement(\"java.util.Map.Entry\")))\n        .isEqualTo(PUBLIC);\n    assertThat(\n            Visibility.ofElement(\n                compilation.getElements().getTypeElement(PublicClass.class.getCanonicalName())))\n        .isEqualTo(PUBLIC);\n    assertThat(\n            Visibility.ofElement(\n                compilation.getElements().getTypeElement(ProtectedClass.class.getCanonicalName())))\n        .isEqualTo(PROTECTED);\n    assertThat(\n            Visibility.ofElement(\n                compilation.getElements().getTypeElement(DefaultClass.class.getCanonicalName())))\n        .isEqualTo(DEFAULT);\n    assertThat(\n            Visibility.ofElement(\n                compilation.getElements().getTypeElement(PrivateClass.class.getCanonicalName())))\n        .isEqualTo(PRIVATE);\n  }\n\n  @Test\n  public void effectiveClassVisibility() {\n    assertThat(effectiveVisiblityOfClass(PublicClass.class)).isEqualTo(PUBLIC);\n    assertThat(effectiveVisiblityOfClass(ProtectedClass.class)).isEqualTo(PROTECTED);\n    assertThat(effectiveVisiblityOfClass(DefaultClass.class)).isEqualTo(DEFAULT);\n    assertThat(effectiveVisiblityOfClass(PrivateClass.class)).isEqualTo(PRIVATE);\n\n    assertThat(effectiveVisiblityOfClass(PublicClass.NestedPublicClass.class)).isEqualTo(PUBLIC);\n    assertThat(effectiveVisiblityOfClass(PublicClass.NestedProtectedClass.class))\n        .isEqualTo(PROTECTED);\n    assertThat(effectiveVisiblityOfClass(PublicClass.NestedDefaultClass.class)).isEqualTo(DEFAULT);\n    assertThat(effectiveVisiblityOfClass(PublicClass.NestedPrivateClass.class)).isEqualTo(PRIVATE);\n\n    assertThat(effectiveVisiblityOfClass(ProtectedClass.NestedPublicClass.class))\n        .isEqualTo(PROTECTED);\n    assertThat(effectiveVisiblityOfClass(ProtectedClass.NestedProtectedClass.class))\n        .isEqualTo(PROTECTED);\n    assertThat(effectiveVisiblityOfClass(ProtectedClass.NestedDefaultClass.class))\n        .isEqualTo(DEFAULT);\n    assertThat(effectiveVisiblityOfClass(ProtectedClass.NestedPrivateClass.class))\n        .isEqualTo(PRIVATE);\n\n    assertThat(effectiveVisiblityOfClass(DefaultClass.NestedPublicClass.class)).isEqualTo(DEFAULT);\n    assertThat(effectiveVisiblityOfClass(DefaultClass.NestedProtectedClass.class))\n        .isEqualTo(DEFAULT);\n    assertThat(effectiveVisiblityOfClass(DefaultClass.NestedDefaultClass.class)).isEqualTo(DEFAULT);\n    assertThat(effectiveVisiblityOfClass(DefaultClass.NestedPrivateClass.class)).isEqualTo(PRIVATE);\n\n    assertThat(effectiveVisiblityOfClass(PrivateClass.NestedPublicClass.class)).isEqualTo(PRIVATE);\n    assertThat(effectiveVisiblityOfClass(PrivateClass.NestedProtectedClass.class))\n        .isEqualTo(PRIVATE);\n    assertThat(effectiveVisiblityOfClass(PrivateClass.NestedDefaultClass.class)).isEqualTo(PRIVATE);\n    assertThat(effectiveVisiblityOfClass(PrivateClass.NestedPrivateClass.class)).isEqualTo(PRIVATE);\n  }\n\n  private Visibility effectiveVisiblityOfClass(Class<?> clazz) {\n    return Visibility.effectiveVisibilityOfElement(\n        compilation.getElements().getTypeElement(clazz.getCanonicalName()));\n  }\n}\n"
  },
  {
    "path": "factory/README.md",
    "content": "AutoFactory\n======\n\nA source code generator for JSR-330-compatible factories.\n\nAutoWhat‽\n-------------\n\n[Java][java] is full of [factories](https://en.wikipedia.org/wiki/Factory_method_pattern). They're mechanical, repetitive, typically untested and sometimes the source of subtle bugs. _Sounds like a job for robots!_\n\nAutoFactory generates factories that can be used on their own or with [JSR-330](https://jcp.org/en/jsr/detail?id=330)-compatible [dependency injectors](https://en.wikipedia.org/wiki/Dependency_injection) from a simple annotation. Any combination of parameters can either be passed through factory methods or provided to the factory at construction time. They can implement interfaces or extend abstract classes. They're what you would have written, but without the bugs.\n\n[Dagger](https://dagger.dev/) users: Dagger's own\n[assisted injection](https://dagger.dev/dev-guide/assisted-injection) is\nnow usually preferred to AutoFactory.\n\nExample\n-------\n\nSay you have:\n\n```java\n@AutoFactory\nfinal class SomeClass {\n  private final String providedDepA;\n  private final String depB;\n\n  SomeClass(@Provided @AQualifier String providedDepA, String depB) {\n    this.providedDepA = providedDepA;\n    this.depB = depB;\n  }\n\n  // …\n}\n```\n\nAutoFactory will generate:\n\n```java\nimport javax.annotation.Generated;\nimport javax.inject.Inject;\nimport javax.inject.Provider;\n\n@Generated(value = \"com.google.auto.factory.processor.AutoFactoryProcessor\")\nfinal class SomeClassFactory {\n  private final Provider<String> providedDepAProvider;\n  \n  @Inject SomeClassFactory(\n      @AQualifier Provider<String> providedDepAProvider) {\n    this.providedDepAProvider = providedDepAProvider;\n  }\n  \n  SomeClass create(String depB) {\n    return new SomeClass(providedDepAProvider.get(), depB);\n  }\n}\n```\n\n> NOTE: AutoFactory only supports JSR-330 @Qualifier annotations. Older, \n> framework-specific annotations from Guice, Spring, etc are not\n> supported (though these all support JSR-330)\n\nMocking\n-------\n\nBy default, the factory class generated by AutoFactory is final, and thus cannot\nbe mocked. The generated factory class can be made mockable by setting\n`allowSubclasses = true`, as follows:\n\n```java\n@AutoFactory(allowSubclasses = true)\nfinal class SomeClass {\n  // …\n}\n```\n\nDownload\n--------\n\nIn order to activate code generation, you will need to include\n`auto-factory-${version}.jar` in both your classpath and your\nannotation-processor path at compile time.\n\nIn a Maven project, one would include the `auto-factory` artifact as an\n\"optional\" dependency and then include it again in `annotationProcessorPaths`:\n\n```xml\n<dependencies>\n  <dependency>\n    <groupId>com.google.auto.factory</groupId>\n    <artifactId>auto-factory</artifactId>\n    <version>${auto-factory.version}</version>\n    <optional>true</optional>\n  </dependency>\n</dependencies>\n\n...\n\n<build>\n  <plugins>\n    <plugin>\n      <artifactId>maven-compiler-plugin</artifactId>\n      <configuration>\n        <annotationProcessorPaths>\n          <path>\n            <groupId>com.google.auto.factory</groupId>\n            <artifactId>auto-factory</artifactId>\n            <version>${auto-factory.version}</version>\n          </path>\n        </annotationProcessorPaths>\n      </configuration>\n    </plugin>\n  </plugins>\n</build>\n```\n\nPrevious versions of these instructions suggested an alternative configuration\nwithout the `annotationProcessorPaths` entry. We no longer recommend that\nconfiguration. (It may produce [warnings or errors][JDK-8321319] under recent\nversions of Java.)\n\n\nLicense\n-------\n\n    Copyright 2013 Google LLC\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n\n[JDK-8321319]: https://bugs.openjdk.org/browse/JDK-8321319\n[java]: https://en.wikipedia.org/wiki/Java_(programming_language)\n"
  },
  {
    "path": "factory/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Copyright 2012 Google LLC\n  Copyright (C) 2012 Square, Inc.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n-->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <groupId>com.google.auto.factory</groupId>\n  <artifactId>auto-factory</artifactId>\n  <version>HEAD-SNAPSHOT</version>\n  <name>AutoFactory</name>\n  <description>\n    JSR-330-compatible factories.\n  </description>\n  <url>https://github.com/google/auto/tree/main/factory</url>\n\n  <properties>\n    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n    <auto-service.version>1.1.1</auto-service.version>\n    <auto-value.version>1.11.1</auto-value.version>\n    <java.version>1.8</java.version>\n    <guava.version>33.5.0-jre</guava.version>\n    <truth.version>1.4.5</truth.version>\n  </properties>\n\n  <scm>\n    <url>http://github.com/google/auto</url>\n    <connection>scm:git:git://github.com/google/auto.git</connection>\n    <developerConnection>scm:git:ssh://git@github.com/google/auto.git</developerConnection>\n    <tag>HEAD</tag>\n  </scm>\n\n  <issueManagement>\n    <system>GitHub Issues</system>\n    <url>http://github.com/google/auto/issues</url>\n  </issueManagement>\n\n  <licenses>\n    <license>\n      <name>Apache 2.0</name>\n      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>\n    </license>\n  </licenses>\n\n  <organization>\n    <name>Google LLC</name>\n    <url>http://www.google.com</url>\n  </organization>\n\n  <developers>\n    <developer>\n      <id>gk5885</id>\n      <name>Gregory Kick</name>\n      <email>gk5885@gmail.com</email>\n      <roles>\n        <role>owner</role>\n        <role>developer</role>\n      </roles>\n      <timezone>-6</timezone>\n    </developer>\n    <developer>\n      <id>eamonnmcmanus</id>\n      <name>Éamonn McManus</name>\n      <email>emcmanus@google.com</email>\n      <organization>Google</organization>\n      <organizationUrl>http://www.google.com</organizationUrl>\n      <roles>\n        <role>owner</role>\n        <role>developer</role>\n      </roles>\n      <timezone>-8</timezone>\n    </developer>\n  </developers>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.jspecify</groupId>\n      <artifactId>jspecify</artifactId>\n      <version>1.0.0</version>\n    </dependency>\n    <dependency>\n      <groupId>com.google.auto</groupId>\n      <artifactId>auto-common</artifactId>\n      <version>1.2.2</version>\n    </dependency>\n    <dependency>\n      <groupId>com.google.auto.value</groupId>\n      <artifactId>auto-value-annotations</artifactId>\n      <version>${auto-value.version}</version>\n    </dependency>\n    <dependency>\n      <groupId>com.google.auto.service</groupId>\n      <artifactId>auto-service-annotations</artifactId>\n      <version>${auto-service.version}</version>\n    </dependency>\n    <dependency>\n      <groupId>net.ltgt.gradle.incap</groupId>\n      <artifactId>incap</artifactId>\n      <version>1.0.0</version>\n      <scope>provided</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>guava</artifactId>\n      <version>${guava.version}</version>\n    </dependency>\n    <dependency>\n      <groupId>com.squareup</groupId>\n      <artifactId>javapoet</artifactId>\n      <version>1.13.0</version>\n    </dependency>\n    <!-- test dependencies -->\n    <dependency>\n      <groupId>javax.inject</groupId>\n      <artifactId>javax.inject</artifactId>\n      <version>1</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>jakarta.inject</groupId>\n      <artifactId>jakarta.inject-api</artifactId>\n      <version>2.0.1</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.testing.compile</groupId>\n      <artifactId>compile-testing</artifactId>\n      <version>0.23.0</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.testparameterinjector</groupId>\n      <artifactId>test-parameter-injector</artifactId>\n      <version>1.21</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>junit</groupId>\n      <artifactId>junit</artifactId>\n      <version>4.13.2</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.truth</groupId>\n      <artifactId>truth</artifactId>\n      <version>${truth.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.code.findbugs</groupId>\n      <artifactId>jsr305</artifactId>\n      <version>3.0.2</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.checkerframework</groupId>\n      <artifactId>checker-compat-qual</artifactId>\n      <version>2.5.6</version>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <artifactId>maven-compiler-plugin</artifactId>\n        <version>3.15.0</version>\n        <configuration>\n          <source>${java.version}</source>\n          <target>${java.version}</target>\n          <compilerArgument>-Xlint:all</compilerArgument>\n          <showWarnings>true</showWarnings>\n          <showDeprecation>true</showDeprecation>\n          <annotationProcessorPaths>\n            <path>\n              <groupId>com.google.auto.service</groupId>\n              <artifactId>auto-service</artifactId>\n              <version>${auto-service.version}</version>\n            </path>\n            <path>\n              <groupId>com.google.auto.value</groupId>\n              <artifactId>auto-value</artifactId>\n              <version>${auto-value.version}</version>\n            </path>\n            <path>\n              <groupId>net.ltgt.gradle.incap</groupId>\n              <artifactId>incap-processor</artifactId>\n              <version>1.0.0</version>\n            </path>\n          </annotationProcessorPaths>\n        </configuration>\n      </plugin>\n      <plugin>\n        <artifactId>maven-javadoc-plugin</artifactId>\n        <version>3.12.0</version>\n        <configuration>\n          <failOnError>false</failOnError>\n        </configuration>\n        <executions>\n          <execution>\n            <id>attach-javadocs</id>\n            <goals>\n              <goal>jar</goal>\n            </goals>\n          </execution>\n        </executions>\n      </plugin>\n      <plugin>\n        <artifactId>maven-source-plugin</artifactId>\n        <version>3.4.0</version>\n        <executions>\n          <execution>\n            <id>attach-sources</id>\n            <goals>\n              <goal>jar-no-fork</goal>\n            </goals>\n          </execution>\n        </executions>\n      </plugin>\n      <plugin>\n        <artifactId>maven-surefire-plugin</artifactId>\n        <version>3.5.5</version>\n        <configuration>\n          <argLine>${test.jvm.flags}</argLine>\n        </configuration>\n      </plugin>\n      <plugin>\n        <artifactId>maven-jar-plugin</artifactId>\n        <version>3.5.0</version>\n      </plugin>\n      <plugin>\n        <artifactId>maven-invoker-plugin</artifactId>\n        <version>3.9.1</version>\n        <configuration>\n          <addTestClassPath>true</addTestClassPath>\n          <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>\n          <localRepositoryPath>${project.build.directory}/it-repo</localRepositoryPath>\n          <pomIncludes>\n            <pomInclude>*/pom.xml</pomInclude>\n          </pomIncludes>\n          <streamLogs>true</streamLogs>\n        </configuration>\n        <executions>\n          <execution>\n            <id>integration-test</id>\n            <goals>\n              <goal>install</goal>\n              <goal>run</goal>\n            </goals>\n          </execution>\n        </executions>\n      </plugin>\n      <plugin>\n        <groupId>org.immutables.tools</groupId>\n        <artifactId>maven-shade-plugin</artifactId>\n        <version>4</version>\n      </plugin>\n      <plugin>\n        <groupId>org.sonatype.central</groupId>\n        <artifactId>central-publishing-maven-plugin</artifactId>\n        <version>0.10.0</version>\n        <extensions>true</extensions>\n      </plugin>\n    </plugins>\n  </build>\n  <profiles>\n    <profile>\n      <id>open-modules</id>\n      <activation>\n        <jdk>[9,)</jdk>\n      </activation>\n      <properties>\n        <test.jvm.flags>\n          --add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED\n          --add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED\n          --add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED\n          --add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED\n          --add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED\n          --add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED\n        </test.jvm.flags>\n      </properties>\n    </profile>\n    <profile>\n      <id>sonatype-oss-release</id>\n      <build>\n        <plugins>\n          <plugin>\n            <artifactId>maven-gpg-plugin</artifactId>\n            <version>3.2.8</version>\n            <executions>\n              <execution>\n                <id>sign-artifacts</id>\n                <phase>verify</phase>\n                <goals>\n                  <goal>sign</goal>\n                </goals>\n              </execution>\n            </executions>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "factory/src/it/functional/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Copyright 2013 Google LLC\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n-->\n<!-- TODO(gak): see if we can manage these dependencies any better -->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n\n  <modelVersion>4.0.0</modelVersion>\n  <groupId>com.google.auto.value.it.functional</groupId>\n  <artifactId>functional</artifactId>\n  <version>HEAD-SNAPSHOT</version>\n  <name>Auto-Value Functional Integration Test</name>\n  <dependencies>\n    <dependency>\n      <groupId>com.google.auto.factory</groupId>\n      <artifactId>auto-factory</artifactId>\n      <version>@project.version@</version>\n    </dependency>\n    <dependency>\n      <groupId>com.google.auto.value</groupId>\n      <artifactId>auto-value-annotations</artifactId>\n      <version>1.11.0</version>\n    </dependency>\n    <dependency>\n      <groupId>com.google.code.findbugs</groupId>\n      <artifactId>jsr305</artifactId>\n      <version>3.0.2</version>\n      <scope>provided</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>guava</artifactId>\n      <version>33.5.0-jre</version>\n    </dependency>\n    <dependency>\n      <groupId>com.google.inject</groupId>\n      <artifactId>guice</artifactId>\n      <version>5.1.0</version>\n    </dependency>\n    <dependency>\n      <groupId>com.google.dagger</groupId>\n      <artifactId>dagger</artifactId>\n      <version>2.42</version>\n    </dependency>\n    <dependency>\n      <groupId>junit</groupId>\n      <artifactId>junit</artifactId>\n      <version>4.13.2</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.truth</groupId>\n      <artifactId>truth</artifactId>\n      <version>1.4.5</version>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-jar-plugin</artifactId>\n        <version>3.2.0</version>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-compiler-plugin</artifactId>\n        <version>3.8.1</version>\n        <configuration>\n          <source>1.8</source>\n          <target>1.8</target>\n          <compilerArgument>-Xlint:all</compilerArgument>\n          <showWarnings>true</showWarnings>\n          <showDeprecation>true</showDeprecation>\n          <annotationProcessorPaths>\n            <path>\n              <groupId>com.google.auto.factory</groupId>\n              <artifactId>auto-factory</artifactId>\n              <version>@project.version@</version>\n            </path>\n            <path>\n              <groupId>com.google.dagger</groupId>\n              <artifactId>dagger-compiler</artifactId>\n              <version>2.42</version>\n            </path>\n          </annotationProcessorPaths>\n        </configuration>\n      </plugin>\n    </plugins>\n  </build>\n</project>\n"
  },
  {
    "path": "factory/src/it/functional/src/main/java/com/google/auto/factory/DaggerModule.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory;\n\nimport com.google.auto.factory.otherpackage.OtherPackage;\nimport dagger.Binds;\nimport dagger.Module;\nimport dagger.Provides;\n\n@Module\nabstract class DaggerModule {\n  private DaggerModule() {} // no instances\n\n  @Binds\n  abstract Dependency provideDependency(DependencyImpl impl);\n\n  @Binds\n  @Qualifier\n  abstract Dependency provideQualifiedDependency(QualifiedDependencyImpl impl);\n\n  @Provides\n  static int providePrimitive() {\n    return 1;\n  }\n\n  @Provides\n  @Qualifier\n  static int provideQualifiedPrimitive() {\n    return 2;\n  }\n\n  @Provides\n  static Number provideNumber() {\n    return 3;\n  }\n\n  @Provides\n  static ReferencePackage provideReferencePackage(ReferencePackageFactory factory) {\n    return factory.create(17);\n  }\n\n  @Provides\n  static OtherPackage provideOtherPackage() {\n    return new OtherPackage(null, 23);\n  }\n}\n"
  },
  {
    "path": "factory/src/it/functional/src/main/java/com/google/auto/factory/Dependency.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory;\n\npublic interface Dependency {}\n"
  },
  {
    "path": "factory/src/it/functional/src/main/java/com/google/auto/factory/DependencyImpl.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory;\n\nimport javax.inject.Inject;\n\npublic class DependencyImpl implements Dependency {\n  @Inject\n  DependencyImpl() {}\n}\n"
  },
  {
    "path": "factory/src/it/functional/src/main/java/com/google/auto/factory/FactoryComponent.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory;\n\nimport com.google.auto.factory.otherpackage.OtherPackageFactory;\nimport dagger.Component;\n\n/** A component to materialize the factory using Dagger 2 */\n@Component(modules = DaggerModule.class)\ninterface FactoryComponent {\n  FooFactory factory();\n\n  GenericFooFactory<Number> generatedFactory();\n\n  ReferencePackageFactory referencePackageFactory();\n\n  OtherPackageFactory otherPackageFactory();\n}\n"
  },
  {
    "path": "factory/src/it/functional/src/main/java/com/google/auto/factory/FactoryInterface.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory;\n\npublic interface FactoryInterface {\n  Foo generate(String name);\n}\n"
  },
  {
    "path": "factory/src/it/functional/src/main/java/com/google/auto/factory/Foo.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory;\n\nimport javax.inject.Provider;\n\n@AutoFactory(implementing = FactoryInterface.class)\npublic final class Foo {\n  private final String name;\n  private final Dependency dependency;\n  private final Provider<Dependency> dependencyProvider;\n  private final int primitive;\n  private final int qualifiedPrimitive;\n\n  Foo(\n      String name,\n      @Provided Dependency dependency,\n      @Provided @Qualifier Provider<Dependency> dependencyProvider,\n      @Provided int primitive,\n      @Provided @Qualifier int qualifiedPrimitive) {\n    this.name = name;\n    this.dependency = dependency;\n    this.dependencyProvider = dependencyProvider;\n    this.primitive = primitive;\n    this.qualifiedPrimitive = qualifiedPrimitive;\n  }\n\n  // Generates second factory method with a different name for the Dependency dependency.\n  // Tests http://b/21632171.\n  Foo(\n      Object name,\n      @Provided Dependency dependency2,\n      @Provided @Qualifier Provider<Dependency> dependencyProvider,\n      @Provided int primitive,\n      @Provided @Qualifier int qualifiedPrimitive) {\n    this(name.toString(), dependency2, dependencyProvider, primitive, qualifiedPrimitive);\n  }\n\n  String name() {\n    return name;\n  }\n\n  Dependency dependency() {\n    return dependency;\n  }\n\n  Provider<Dependency> dependencyProvider() {\n    return dependencyProvider;\n  }\n\n  int primitive() {\n    return primitive;\n  }\n\n  int qualifiedPrimitive() {\n    return qualifiedPrimitive;\n  }\n}\n"
  },
  {
    "path": "factory/src/it/functional/src/main/java/com/google/auto/factory/GenericFoo.java",
    "content": "/*\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory;\n\nimport java.util.List;\nimport javax.inject.Provider;\n\n@AutoFactory\npublic class GenericFoo<A, B extends List<? extends A>, C, E extends Enum<E>> {\n\n  private final A depA;\n  private final B depB;\n  private final IntAccessor depDIntAccessor;\n  private final StringAccessor depDStringAccessor;\n  private final E depE;\n\n  <D extends IntAccessor & StringAccessor> GenericFoo(\n      @Provided Provider<A> depA, B depB, D depD, E depE) {\n    this.depA = depA.get();\n    this.depB = depB;\n    this.depDIntAccessor = depD;\n    this.depDStringAccessor = depD;\n    this.depE = depE;\n  }\n\n  public A getDepA() {\n    return depA;\n  }\n\n  public B getDepB() {\n    return depB;\n  }\n\n  public C passThrough(C value) {\n    return value;\n  }\n\n  public IntAccessor getDepDIntAccessor() {\n    return depDIntAccessor;\n  }\n\n  public StringAccessor getDepDStringAccessor() {\n    return depDStringAccessor;\n  }\n\n  public E getDepE() {\n    return depE;\n  }\n\n  public interface IntAccessor {}\n\n  public interface StringAccessor {}\n\n  public interface IntAndStringAccessor extends IntAccessor, StringAccessor {}\n\n  public enum DepE {\n    VALUE_1,\n    VALUE_2\n  }\n}\n"
  },
  {
    "path": "factory/src/it/functional/src/main/java/com/google/auto/factory/GuiceModule.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory;\n\nimport com.google.inject.AbstractModule;\n\npublic class GuiceModule extends AbstractModule {\n  @Override\n  protected void configure() {\n    bind(Dependency.class).to(DependencyImpl.class);\n    bind(Dependency.class).annotatedWith(Qualifier.class).to(QualifiedDependencyImpl.class);\n    bind(Integer.class).toInstance(1);\n    bind(Integer.class).annotatedWith(Qualifier.class).toInstance(2);\n    bind(Number.class).toInstance(3);\n  }\n}\n"
  },
  {
    "path": "factory/src/it/functional/src/main/java/com/google/auto/factory/QualifiedDependencyImpl.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory;\n\nimport javax.inject.Inject;\n\npublic class QualifiedDependencyImpl implements Dependency {\n  @Inject\n  QualifiedDependencyImpl() {}\n}\n"
  },
  {
    "path": "factory/src/it/functional/src/main/java/com/google/auto/factory/Qualifier.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\n\n@javax.inject.Qualifier\n@Retention(RetentionPolicy.RUNTIME)\n@interface Qualifier {}\n"
  },
  {
    "path": "factory/src/it/functional/src/main/java/com/google/auto/factory/ReferencePackage.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory;\n\nimport com.google.auto.factory.otherpackage.OtherPackage;\nimport com.google.auto.factory.otherpackage.OtherPackageFactory;\nimport javax.inject.Inject;\n\n@AutoFactory\npublic class ReferencePackage {\n  private final OtherPackageFactory otherPackageFactory;\n  private final int random;\n\n  @Inject\n  ReferencePackage(@Provided OtherPackageFactory otherPackageFactory, int random) {\n    this.otherPackageFactory = otherPackageFactory;\n    this.random = random;\n  }\n\n  public OtherPackage otherPackage() {\n    return otherPackageFactory.create(random);\n  }\n}\n"
  },
  {
    "path": "factory/src/it/functional/src/main/java/com/google/auto/factory/otherpackage/OtherPackage.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.otherpackage;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.Provided;\nimport com.google.auto.factory.ReferencePackageFactory;\n\n@AutoFactory\npublic class OtherPackage {\n  private final ReferencePackageFactory referencePackageFactory;\n  private final int random;\n\n  public OtherPackage(@Provided ReferencePackageFactory referencePackageFactory, int random) {\n    this.referencePackageFactory = referencePackageFactory;\n    this.random = random;\n  }\n\n  public ReferencePackageFactory referencePackageFactory() {\n    return referencePackageFactory;\n  }\n\n  public int random() {\n    return random;\n  }\n}\n"
  },
  {
    "path": "factory/src/it/functional/src/test/java/com/google/auto/factory/DependencyInjectionIntegrationTest.java",
    "content": "package com.google.auto.factory;\n\nimport static com.google.common.truth.Truth.assertThat;\n\nimport com.google.auto.factory.GenericFoo.DepE;\nimport com.google.auto.factory.GenericFoo.IntAndStringAccessor;\nimport com.google.auto.factory.otherpackage.OtherPackage;\nimport com.google.common.collect.ImmutableList;\nimport com.google.inject.Guice;\nimport com.google.inject.Key;\nimport com.google.inject.TypeLiteral;\nimport java.util.ArrayList;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic class DependencyInjectionIntegrationTest {\n\n  private static final IntAndStringAccessor INT_AND_STRING_ACCESSOR = new IntAndStringAccessor() {};\n\n  @Test\n  public void daggerInjectedFactory() {\n    FooFactory fooFactory = DaggerFactoryComponent.create().factory();\n    Foo one = fooFactory.create(\"A\");\n    Foo two = fooFactory.create(\"B\");\n    assertThat(one.name()).isEqualTo(\"A\");\n    assertThat(one.dependency()).isNotNull();\n    assertThat(one.dependencyProvider()).isNotNull();\n    assertThat(one.dependencyProvider().get()).isInstanceOf(QualifiedDependencyImpl.class);\n    assertThat(one.primitive()).isEqualTo(1);\n    assertThat(one.qualifiedPrimitive()).isEqualTo(2);\n    assertThat(two.name()).isEqualTo(\"B\");\n    assertThat(two.dependency()).isNotNull();\n    assertThat(two.dependency()).isNotEqualTo(one.dependency());\n    assertThat(two.dependencyProvider()).isNotNull();\n    assertThat(two.dependencyProvider().get()).isInstanceOf(QualifiedDependencyImpl.class);\n    assertThat(two.primitive()).isEqualTo(1);\n    assertThat(two.qualifiedPrimitive()).isEqualTo(2);\n  }\n\n  @Test\n  public void daggerInjectedGenericFactory() {\n    GenericFooFactory<Number> genericFooFactory =\n        DaggerFactoryComponent.create().generatedFactory();\n    GenericFoo<Number, ImmutableList<Long>, String, DepE> three =\n        genericFooFactory.create(ImmutableList.of(3L), INT_AND_STRING_ACCESSOR, DepE.VALUE_1);\n    ArrayList<Double> intAndStringAccessorArrayList = new ArrayList<>();\n    intAndStringAccessorArrayList.add(4.0);\n    GenericFoo<Number, ArrayList<Double>, Long, DepE> four =\n        genericFooFactory.create(\n            intAndStringAccessorArrayList, INT_AND_STRING_ACCESSOR, DepE.VALUE_2);\n    assertThat(three.getDepA()).isEqualTo(3);\n    ImmutableList<Long> unusedLongList = three.getDepB();\n    assertThat(three.getDepB()).containsExactly(3L);\n    assertThat(three.getDepDIntAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);\n    assertThat(three.getDepDStringAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);\n    assertThat(three.passThrough(\"value\")).isEqualTo(\"value\");\n    assertThat(three.getDepE()).isEqualTo(DepE.VALUE_1);\n    assertThat(four.getDepA()).isEqualTo(3);\n    ArrayList<Double> unusedDoubleList = four.getDepB();\n    assertThat(four.getDepB()).isInstanceOf(ArrayList.class);\n    assertThat(four.getDepB()).containsExactly(4.0);\n    assertThat(four.getDepDIntAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);\n    assertThat(four.getDepDStringAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);\n    assertThat(four.passThrough(5L)).isEqualTo(5L);\n    assertThat(four.getDepE()).isEqualTo(DepE.VALUE_2);\n  }\n\n  @Test\n  public void daggerInjectedPackageSpanningFactory() {\n    FactoryComponent component = DaggerFactoryComponent.create();\n    ReferencePackageFactory referencePackageFactory = component.referencePackageFactory();\n    ReferencePackage referencePackage = referencePackageFactory.create(5);\n    OtherPackage otherPackage = referencePackage.otherPackage();\n    assertThat(otherPackage.referencePackageFactory()).isNotSameInstanceAs(referencePackageFactory);\n    assertThat(otherPackage.random()).isEqualTo(5);\n  }\n\n  @Test\n  public void guiceInjectedFactory() {\n    FooFactory fooFactory = Guice.createInjector(new GuiceModule()).getInstance(FooFactory.class);\n    Foo one = fooFactory.create(\"A\");\n    Foo two = fooFactory.create(\"B\");\n    assertThat(one.name()).isEqualTo(\"A\");\n    assertThat(one.dependency()).isNotNull();\n    assertThat(one.dependencyProvider()).isNotNull();\n    assertThat(one.dependencyProvider().get()).isInstanceOf(QualifiedDependencyImpl.class);\n    assertThat(one.primitive()).isEqualTo(1);\n    assertThat(one.qualifiedPrimitive()).isEqualTo(2);\n    assertThat(two.name()).isEqualTo(\"B\");\n    assertThat(two.dependency()).isNotNull();\n    assertThat(two.dependency()).isNotEqualTo(one.dependency());\n    assertThat(two.dependencyProvider()).isNotNull();\n    assertThat(two.dependencyProvider().get()).isInstanceOf(QualifiedDependencyImpl.class);\n    assertThat(two.primitive()).isEqualTo(1);\n    assertThat(two.qualifiedPrimitive()).isEqualTo(2);\n  }\n\n  @Test\n  public void guiceInjectedGenericFactory() {\n    GenericFooFactory<Number> genericFooFactory =\n        Guice.createInjector(new GuiceModule())\n            .getInstance(Key.get(new TypeLiteral<GenericFooFactory<Number>>() {}));\n    GenericFoo<Number, ImmutableList<Long>, String, DepE> three =\n        genericFooFactory.create(ImmutableList.of(3L), INT_AND_STRING_ACCESSOR, DepE.VALUE_1);\n    ArrayList<Double> intAndStringAccessorArrayList = new ArrayList<>();\n    intAndStringAccessorArrayList.add(4.0);\n    GenericFoo<Number, ArrayList<Double>, Long, DepE> four =\n        genericFooFactory.create(\n            intAndStringAccessorArrayList, INT_AND_STRING_ACCESSOR, DepE.VALUE_2);\n    assertThat(three.getDepA()).isEqualTo(3);\n    ImmutableList<Long> unusedLongList = three.getDepB();\n    assertThat(three.getDepB()).containsExactly(3L);\n    assertThat(three.getDepDIntAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);\n    assertThat(three.getDepDStringAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);\n    assertThat(three.passThrough(\"value\")).isEqualTo(\"value\");\n    assertThat(three.getDepE()).isEqualTo(DepE.VALUE_1);\n    assertThat(four.getDepA()).isEqualTo(3);\n    ArrayList<Double> unusedDoubleList = four.getDepB();\n    assertThat(four.getDepB()).containsExactly(4.0);\n    assertThat(four.getDepDIntAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);\n    assertThat(four.getDepDStringAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);\n    assertThat(four.passThrough(5L)).isEqualTo(5L);\n    assertThat(four.getDepE()).isEqualTo(DepE.VALUE_2);\n  }\n\n  @Test\n  public void guiceInjectedPackageSpanningFactory() {\n    ReferencePackageFactory referencePackageFactory =\n        Guice.createInjector(new GuiceModule()).getInstance(ReferencePackageFactory.class);\n    ReferencePackage referencePackage = referencePackageFactory.create(5);\n    OtherPackage otherPackage = referencePackage.otherPackage();\n    assertThat(otherPackage.referencePackageFactory()).isNotSameInstanceAs(referencePackageFactory);\n    assertThat(otherPackage.random()).isEqualTo(5);\n  }\n}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/AutoFactory.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory;\n\nimport static java.lang.annotation.ElementType.ANNOTATION_TYPE;\nimport static java.lang.annotation.ElementType.CONSTRUCTOR;\nimport static java.lang.annotation.ElementType.TYPE;\n\nimport java.lang.annotation.Target;\n\n/**\n * An annotation to be applied to elements for which a factory should be automatically generated.\n *\n * <h2>Visibility</h2>\n *\n * <p>The visibility of the generated factories will always be either {@code public} or default\n * visibility. The visibility of any given factory method is determined by the visibility of the\n * type being created. The generated factory is {@code public} if any of the factory methods are.\n * Any method that implements an interface method is necessarily public and any method that\n * overrides an abstract method has the same visibility as that method.\n *\n * @author Gregory Kick\n */\n@Target({TYPE, CONSTRUCTOR})\npublic @interface AutoFactory {\n  /**\n   * The <i>simple</i> name of the generated factory; the factory is always generated in the same\n   * package as the annotated type. The default value (the empty string) will result in a factory\n   * with the name of the type being created with {@code Factory} appended to the end. For example,\n   * the default name for a factory for {@code MyType} will be {@code MyTypeFactory}.\n   *\n   * <p>If the annotated type is nested, then the generated factory's name will start with the\n   * enclosing type names, separated by underscores. For example, the default name for a factory for\n   * {@code Outer.Inner.ReallyInner} is {@code Outer_Inner_ReallyInnerFactory}. If {@code className}\n   * is {@code Foo}, then the factory name is {@code Outer_Inner_Foo}.\n   */\n  String className() default \"\";\n\n  /** A list of interfaces that the generated factory is required to implement. */\n  Class<?>[] implementing() default {};\n\n  /** The type that the generated factory is required to extend. */\n  Class<?> extending() default Object.class;\n\n  /**\n   * Whether or not the generated factory should be final. Defaults to disallowing subclasses\n   * (generating the factory as final).\n   */\n  boolean allowSubclasses() default false;\n\n  /**\n   * Specifies that an annotation should be used to determine how to annotate generated AutoFactory\n   * classes. For example, suppose you have this annotation:\n   * <pre>{@code\n   * @AutoFactory.AnnotationsToApply\n   * @interface ApplyImmutableAndSuppressWarnings {\n   *   Immutable immutable() default @Immutable;\n   *   SuppressWarnings suppressWarnings() default @SuppressWarnings(\"Immutable\");\n   * }\n   * }</pre>\n   *\n   * And suppose you use it like this:\n   * <pre>{@code\n   * @ApplyImmutableAndSuppressWarnings\n   * @AutoFactory\n   * public class Foo {...}\n   * }</pre>\n   *\n   * Then the generated {@code FooFactory} would look like this:\n   * <pre>{@code\n   * @Immutable\n   * @SuppressWarnings(\"Immutable\")\n   * public class FooFactory {...}\n   * }</pre>\n   *\n   * The same would be true if you used it like this:\n   * <pre>{@code\n   * @ApplyImmutableAndSuppressWarnings(\n   *     immutable = @Immutable,\n   *     suppressWarnings = @SuppressWarnings(\"Immutable\"))\n   * @AutoFactory\n   * public class Foo {...}\n   * }</pre>\n   *\n   * You could also have {@code suppressWarnings = @SuppressWarnings({\"Immutable\", \"unchecked\"})},\n   * etc, to specify a value different from the default.\n   */\n  @Target(ANNOTATION_TYPE)\n  @interface AnnotationsToApply {}\n}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/Provided.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory;\n\nimport static java.lang.annotation.ElementType.PARAMETER;\n\nimport java.lang.annotation.Target;\n\n/**\n * An annotation to be applied to parameters that should be provided by an injected {@code Provider}\n * in a generated factory.\n *\n * <p>The {@code @Inject} and {@code Provider} classes come from either the legacy package {@code\n * javax.inject} or the updated package {@code jakarta.inject}. {@code jakarta.inject} is used if it\n * is on the classpath. Compile with {@code -Acom.google.auto.factory.InjectApi=javax} if you want\n * to use {@code javax.inject} even when {@code jakarta.inject} is available.\n *\n * @author Gregory Kick\n */\n@Target(PARAMETER)\npublic @interface Provided {}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/package-info.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n@NullMarked\npackage com.google.auto.factory;\n\nimport org.jspecify.annotations.NullMarked;\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/processor/AnnotationValues.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.Iterables;\nimport java.util.List;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.ElementFilter;\nimport javax.lang.model.util.SimpleAnnotationValueVisitor6;\nimport javax.lang.model.util.SimpleTypeVisitor6;\n\nfinal class AnnotationValues {\n  private AnnotationValues() {}\n\n  static boolean asBoolean(AnnotationValue value) {\n    return value.accept(\n        new SimpleAnnotationValueVisitor6<Boolean, Void>() {\n          @Override\n          protected Boolean defaultAction(Object o, Void p) {\n            throw new IllegalArgumentException();\n          }\n\n          @Override\n          public Boolean visitBoolean(boolean b, Void p) {\n            return b;\n          }\n        },\n        null);\n  }\n\n  static TypeElement asType(AnnotationValue value) {\n    return value.accept(\n        new SimpleAnnotationValueVisitor6<TypeElement, Void>() {\n          @Override\n          protected TypeElement defaultAction(Object o, Void p) {\n            throw new IllegalArgumentException();\n          }\n\n          @Override\n          public TypeElement visitType(TypeMirror t, Void p) {\n            return t.accept(\n                new SimpleTypeVisitor6<TypeElement, Void>() {\n                  @Override\n                  protected TypeElement defaultAction(TypeMirror e, Void p) {\n                    throw new AssertionError();\n                  }\n\n                  @Override\n                  public TypeElement visitDeclared(DeclaredType t, Void p) {\n                    return Iterables.getOnlyElement(\n                        ElementFilter.typesIn(ImmutableList.of(t.asElement())));\n                  }\n                },\n                null);\n          }\n        },\n        null);\n  }\n\n  static ImmutableList<? extends AnnotationValue> asList(AnnotationValue value) {\n    return value.accept(\n        new SimpleAnnotationValueVisitor6<ImmutableList<? extends AnnotationValue>, Void>() {\n          @Override\n          protected ImmutableList<? extends AnnotationValue> defaultAction(Object o, Void p) {\n            throw new IllegalArgumentException();\n          }\n\n          @Override\n          public ImmutableList<? extends AnnotationValue> visitArray(\n              List<? extends AnnotationValue> vals, Void p) {\n            return ImmutableList.copyOf(vals);\n          }\n        },\n        null);\n  }\n}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/processor/AutoFactoryDeclaration.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport static com.google.auto.common.MoreElements.getPackage;\nimport static com.google.auto.factory.processor.Elements2.isValidSupertypeForClass;\nimport static com.google.common.base.Preconditions.checkArgument;\nimport static com.google.common.base.Preconditions.checkNotNull;\nimport static com.google.common.collect.ImmutableSet.toImmutableSet;\nimport static com.google.common.collect.Iterables.getOnlyElement;\nimport static java.util.Objects.requireNonNull;\nimport static javax.lang.model.element.ElementKind.PACKAGE;\nimport static javax.lang.model.util.ElementFilter.typesIn;\nimport static javax.tools.Diagnostic.Kind.ERROR;\n\nimport com.google.auto.common.AnnotationMirrors;\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.AutoFactory.AnnotationsToApply;\nimport com.google.auto.value.AutoValue;\nimport com.google.common.base.Predicate;\nimport com.google.common.collect.FluentIterable;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport javax.annotation.processing.Messager;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.util.ElementFilter;\nimport javax.lang.model.util.Elements;\n\n/**\n * This is a value object that mirrors the static declaration of an {@link AutoFactory} annotation.\n *\n * @author Gregory Kick\n */\n@AutoValue\nabstract class AutoFactoryDeclaration {\n  abstract TypeElement targetType();\n\n  abstract Element target();\n\n  abstract Optional<String> className();\n\n  abstract ImmutableSet<AnnotationMirror> annotations();\n\n  abstract TypeElement extendingType();\n\n  abstract ImmutableSet<TypeElement> implementingTypes();\n\n  abstract boolean allowSubclasses();\n\n  abstract AnnotationMirror mirror();\n\n  abstract ImmutableMap<String, AnnotationValue> valuesMap();\n\n  PackageAndClass getFactoryName() {\n    String packageName = getPackage(targetType()).getQualifiedName().toString();\n    if (className().isPresent()) {\n      return PackageAndClass.of(packageName, className().get());\n    }\n    StringBuilder builder = new StringBuilder();\n    for (String enclosingSimpleName : targetEnclosingSimpleNames()) {\n      builder.append(enclosingSimpleName).append('_');\n    }\n    builder.append(targetType().getSimpleName()).append(\"Factory\");\n    return PackageAndClass.of(packageName, builder.toString());\n  }\n\n  private ImmutableList<String> targetEnclosingSimpleNames() {\n    ImmutableList.Builder<String> simpleNames = ImmutableList.builder();\n    for (Element element = targetType().getEnclosingElement();\n        !element.getKind().equals(PACKAGE);\n        element = element.getEnclosingElement()) {\n      simpleNames.add(element.getSimpleName().toString());\n    }\n    return simpleNames.build().reverse();\n  }\n\n  static final class Factory {\n    private final Elements elements;\n    private final Messager messager;\n\n    Factory(Elements elements, Messager messager) {\n      this.elements = elements;\n      this.messager = messager;\n    }\n\n    Optional<AutoFactoryDeclaration> createIfValid(Element element) {\n      checkNotNull(element);\n      AnnotationMirror mirror = Mirrors.getAnnotationMirror(element, AutoFactory.class).get();\n      checkArgument(\n          Mirrors.getQualifiedName(mirror.getAnnotationType())\n              .contentEquals(AutoFactory.class.getName()));\n      Map<String, AnnotationValue> values =\n          Mirrors.simplifyAnnotationValueMap(elements.getElementValuesWithDefaults(mirror));\n\n      // className value is a string, so we can just call toString. We know values.get(\"className\")\n      // is non-null because @AutoFactory has an annotation element of that name.\n      AnnotationValue classNameValue = requireNonNull(values.get(\"className\"));\n      String className = classNameValue.getValue().toString();\n      if (!className.isEmpty() && !isValidIdentifier(className)) {\n        messager.printMessage(\n            ERROR,\n            String.format(\"\\\"%s\\\" is not a valid Java identifier\", className),\n            element,\n            mirror,\n            classNameValue);\n        return Optional.empty();\n      }\n\n      ImmutableSet<AnnotationMirror> annotations = annotationsToAdd(element);\n      AnnotationValue extendingValue = checkNotNull(values.get(\"extending\"));\n      TypeElement extendingType = AnnotationValues.asType(extendingValue);\n      if (extendingType == null) {\n        messager.printMessage(\n            ERROR,\n            \"Unable to find the type: \" + extendingValue.getValue(),\n            element,\n            mirror,\n            extendingValue);\n        return Optional.empty();\n      } else if (!isValidSupertypeForClass(extendingType)) {\n        messager.printMessage(\n            ERROR,\n            String.format(\n                \"%s is not a valid supertype for a factory. \"\n                    + \"Supertypes must be non-final classes.\",\n                extendingType.getQualifiedName()),\n            element,\n            mirror,\n            extendingValue);\n        return Optional.empty();\n      }\n      ImmutableList<ExecutableElement> noParameterConstructors =\n          FluentIterable.from(ElementFilter.constructorsIn(extendingType.getEnclosedElements()))\n              .filter(\n                  new Predicate<ExecutableElement>() {\n                    @Override\n                    public boolean apply(ExecutableElement constructor) {\n                      return constructor.getParameters().isEmpty();\n                    }\n                  })\n              .toList();\n      if (noParameterConstructors.isEmpty()) {\n        messager.printMessage(\n            ERROR,\n            String.format(\n                \"%s is not a valid supertype for a factory. \"\n                    + \"Factory supertypes must have a no-arg constructor.\",\n                extendingType.getQualifiedName()),\n            element,\n            mirror,\n            extendingValue);\n        return Optional.empty();\n      } else if (noParameterConstructors.size() > 1) {\n        throw new IllegalStateException(\"Multiple constructors with no parameters??\");\n      }\n\n      AnnotationValue implementingValue = checkNotNull(values.get(\"implementing\"));\n      ImmutableSet.Builder<TypeElement> builder = ImmutableSet.builder();\n      for (AnnotationValue implementingTypeValue : AnnotationValues.asList(implementingValue)) {\n        builder.add(AnnotationValues.asType(implementingTypeValue));\n      }\n      ImmutableSet<TypeElement> implementingTypes = builder.build();\n\n      AnnotationValue allowSubclassesValue = checkNotNull(values.get(\"allowSubclasses\"));\n      boolean allowSubclasses = AnnotationValues.asBoolean(allowSubclassesValue);\n\n      return Optional.<AutoFactoryDeclaration>of(\n          new AutoValue_AutoFactoryDeclaration(\n              getAnnotatedType(element),\n              element,\n              className.isEmpty() ? Optional.empty() : Optional.of(className),\n              annotations,\n              extendingType,\n              implementingTypes,\n              allowSubclasses,\n              mirror,\n              ImmutableMap.copyOf(values)));\n    }\n\n    private static TypeElement getAnnotatedType(Element element) {\n      List<TypeElement> types = ImmutableList.of();\n      while (types.isEmpty()) {\n        types = typesIn(Arrays.asList(element));\n        element = element.getEnclosingElement();\n      }\n      return getOnlyElement(types);\n    }\n\n    static boolean isValidIdentifier(String identifier) {\n      return SourceVersion.isIdentifier(identifier) && !SourceVersion.isKeyword(identifier);\n    }\n\n    private ImmutableSet<AnnotationMirror> annotationsToAdd(Element element) {\n      ImmutableSet<? extends AnnotationMirror> containers =\n          AnnotationMirrors.getAnnotatedAnnotations(element, AnnotationsToApply.class);\n      if (containers.size() > 1) {\n        messager.printMessage(\n            ERROR, \"Multiple @AnnotationsToApply annotations are not supported\", element);\n      }\n      return containers.stream()\n          .limit(1)\n          .map(elements::getElementValuesWithDefaults)\n          .map(Map::values)\n          .flatMap(Collection::stream)\n          .map(AnnotationValue::getValue)\n          .filter(AnnotationMirror.class::isInstance)\n          // Any non-annotation element should already have been flagged when processing\n          // @AnnotationsToApply\n          .map(AnnotationMirror.class::cast)\n          .collect(toImmutableSet());\n    }\n  }\n}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/processor/AutoFactoryProcessor.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport static com.google.auto.common.MoreTypes.asElement;\nimport static com.google.auto.common.MoreTypes.asTypeElement;\nimport static javax.lang.model.element.ElementKind.ANNOTATION_TYPE;\nimport static javax.lang.model.type.TypeKind.DECLARED;\nimport static javax.lang.model.type.TypeKind.ERROR;\nimport static javax.lang.model.util.ElementFilter.methodsIn;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.AutoFactory.AnnotationsToApply;\nimport com.google.auto.factory.Provided;\nimport com.google.auto.service.AutoService;\nimport com.google.common.base.Throwables;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableListMultimap;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.ImmutableSetMultimap;\nimport com.google.common.collect.ImmutableSortedSet;\nimport com.google.common.collect.Iterables;\nimport java.io.IOException;\nimport java.util.Arrays;\nimport java.util.Comparator;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Optional;\nimport java.util.Set;\nimport java.util.function.Consumer;\nimport javax.annotation.processing.AbstractProcessor;\nimport javax.annotation.processing.Messager;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.annotation.processing.Processor;\nimport javax.annotation.processing.RoundEnvironment;\nimport javax.annotation.processing.SupportedOptions;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.Modifier;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.ExecutableType;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.ElementFilter;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.Types;\nimport javax.tools.Diagnostic.Kind;\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessor;\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;\nimport org.jspecify.annotations.Nullable;\n\n/**\n * The annotation processor that generates factories for {@link AutoFactory} annotations.\n *\n * @author Gregory Kick\n */\n@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.ISOLATING)\n@AutoService(Processor.class)\n@SupportedOptions(AutoFactoryProcessor.INJECT_API_OPTION)\npublic final class AutoFactoryProcessor extends AbstractProcessor {\n  static final String INJECT_API_OPTION = \"com.google.auto.factory.InjectApi\";\n\n  private static final ImmutableSet<String> INJECT_APIS = ImmutableSet.of(\"jakarta\", \"javax\");\n\n  private FactoryDescriptorGenerator factoryDescriptorGenerator;\n  private AutoFactoryDeclaration.Factory declarationFactory;\n  private ProvidedChecker providedChecker;\n  private Messager messager;\n  private Elements elements;\n  private Types types;\n  private InjectApi injectApi;\n\n  /**\n   * If non-null, we will call this whenever the {@link #process} method is called, giving it one of\n   * the {@code @AutoFactory} elements, and do nothing else.\n   */\n  private @Nullable Consumer<@Nullable Element> errorFunction;\n\n  @Override\n  public synchronized void init(ProcessingEnvironment processingEnv) {\n    super.init(processingEnv);\n    elements = processingEnv.getElementUtils();\n    types = processingEnv.getTypeUtils();\n    messager = processingEnv.getMessager();\n    String api = processingEnv.getOptions().get(INJECT_API_OPTION);\n    if (api != null && !INJECT_APIS.contains(api)) {\n      messager.printMessage(\n          Kind.ERROR,\n          \"Usage: -A\"\n              + INJECT_API_OPTION\n              + \"=<api>, where <api> is \"\n              + String.join(\" or \", INJECT_APIS));\n      errorFunction = unused -> {};\n      return;\n    }\n    try {\n      injectApi = InjectApi.from(elements, api);\n    } catch (IllegalStateException e) {\n      errorFunction =\n          element -> {\n            messager.printMessage(Kind.ERROR, e.getMessage(), element);\n            errorFunction = unused -> {}; // Only print the error once.\n          };\n      return;\n    }\n    providedChecker = new ProvidedChecker(messager);\n    declarationFactory = new AutoFactoryDeclaration.Factory(elements, messager);\n    factoryDescriptorGenerator =\n        new FactoryDescriptorGenerator(messager, types, declarationFactory, injectApi);\n  }\n\n  @Override\n  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n    if (errorFunction != null) {\n      Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(AutoFactory.class);\n      Element anElement = elements.isEmpty() ? null : elements.iterator().next();\n      errorFunction.accept(anElement);\n      return false;\n    }\n    try {\n      doProcess(roundEnv);\n    } catch (Throwable e) {\n      messager.printMessage(\n          Kind.ERROR,\n          \"Failed to process @AutoFactory annotations:\\n\" + Throwables.getStackTraceAsString(e));\n    }\n    return false;\n  }\n\n  private void doProcess(RoundEnvironment roundEnv) {\n    for (Element element : roundEnv.getElementsAnnotatedWith(Provided.class)) {\n      providedChecker.checkProvidedParameter(element);\n    }\n\n    for (Element element : roundEnv.getElementsAnnotatedWith(AnnotationsToApply.class)) {\n      checkAnnotationsToApply(element);\n    }\n\n    ImmutableListMultimap.Builder<PackageAndClass, FactoryMethodDescriptor> indexedMethodsBuilder =\n        ImmutableListMultimap.builder();\n    ImmutableSetMultimap.Builder<PackageAndClass, ImplementationMethodDescriptor>\n        implementationMethodDescriptorsBuilder = ImmutableSetMultimap.builder();\n    // Iterate over the classes and constructors that are annotated with @AutoFactory.\n    for (Element element : roundEnv.getElementsAnnotatedWith(AutoFactory.class)) {\n      Optional<AutoFactoryDeclaration> declaration = declarationFactory.createIfValid(element);\n      if (declaration.isPresent()) {\n        PackageAndClass factoryName = declaration.get().getFactoryName();\n        TypeElement extendingType = declaration.get().extendingType();\n        implementationMethodDescriptorsBuilder.putAll(\n            factoryName, implementationMethods(extendingType, element));\n        for (TypeElement implementingType : declaration.get().implementingTypes()) {\n          implementationMethodDescriptorsBuilder.putAll(\n              factoryName, implementationMethods(implementingType, element));\n        }\n      }\n\n      ImmutableSet<FactoryMethodDescriptor> descriptors =\n          factoryDescriptorGenerator.generateDescriptor(element);\n      for (FactoryMethodDescriptor descriptor : descriptors) {\n        indexedMethodsBuilder.put(descriptor.factoryName(), descriptor);\n      }\n    }\n\n    ImmutableSetMultimap<PackageAndClass, ImplementationMethodDescriptor>\n        implementationMethodDescriptors = implementationMethodDescriptorsBuilder.build();\n    ImmutableListMultimap<PackageAndClass, FactoryMethodDescriptor> indexedMethods =\n        indexedMethodsBuilder.build();\n    ImmutableSetMultimap<String, PackageAndClass> factoriesBeingCreated =\n        simpleNamesToNames(indexedMethods.keySet());\n    FactoryWriter factoryWriter =\n        new FactoryWriter(processingEnv, injectApi, factoriesBeingCreated);\n\n    indexedMethods\n        .asMap()\n        .forEach(\n            (factoryName, methodDescriptors) -> {\n              if (methodDescriptors.isEmpty()) {\n                // This shouldn't happen, but check anyway to avoid an exception for\n                // methodDescriptors.iterator().next() below.\n                return;\n              }\n              // Sort to ensure output is deterministic.\n              ImmutableSortedSet.Builder<AnnotationMirror> annotationsBuilder =\n                  ImmutableSortedSet.orderedBy(ANNOTATION_COMPARATOR);\n              // The sets of classes that are mentioned in the `extending` and `implementing`\n              // elements, respectively, of the @AutoFactory annotations for this factory.\n              ImmutableSet.Builder<TypeMirror> extending = newTypeSetBuilder();\n              ImmutableSortedSet.Builder<TypeMirror> implementing = newTypeSetBuilder();\n              boolean publicType = false;\n              Set<Boolean> allowSubclassesSet = new HashSet<>();\n              boolean skipCreation = false;\n              for (FactoryMethodDescriptor methodDescriptor : methodDescriptors) {\n                annotationsBuilder.addAll(methodDescriptor.declaration().annotations());\n                extending.add(methodDescriptor.declaration().extendingType().asType());\n                for (TypeElement implementingType :\n                    methodDescriptor.declaration().implementingTypes()) {\n                  implementing.add(implementingType.asType());\n                }\n                publicType |= methodDescriptor.publicMethod();\n                allowSubclassesSet.add(methodDescriptor.declaration().allowSubclasses());\n                if (allowSubclassesSet.size() > 1) {\n                  skipCreation = true;\n                  messager.printMessage(\n                      Kind.ERROR,\n                      \"Cannot mix allowSubclasses=true and allowSubclasses=false in one factory.\",\n                      methodDescriptor.declaration().target(),\n                      methodDescriptor.declaration().mirror(),\n                      methodDescriptor.declaration().valuesMap().get(\"allowSubclasses\"));\n                }\n              }\n              // The set can't be empty because we eliminated methodDescriptors.isEmpty() above.\n              boolean allowSubclasses = allowSubclassesSet.iterator().next();\n              if (!skipCreation) {\n                try {\n                  factoryWriter.writeFactory(\n                      FactoryDescriptor.create(\n                          factoryName,\n                          annotationsBuilder.build(),\n                          Iterables.getOnlyElement(extending.build()),\n                          implementing.build(),\n                          publicType,\n                          ImmutableSet.copyOf(methodDescriptors),\n                          implementationMethodDescriptors.get(factoryName),\n                          allowSubclasses));\n                } catch (IOException e) {\n                  messager.printMessage(Kind.ERROR, \"failed: \" + e);\n                }\n              }\n            });\n  }\n\n  private static final Comparator<AnnotationMirror> ANNOTATION_COMPARATOR =\n      Comparator.comparing(mirror -> mirror.getAnnotationType().toString());\n\n  private ImmutableSet<ImplementationMethodDescriptor> implementationMethods(\n      TypeElement supertype, Element autoFactoryElement) {\n    ImmutableSet.Builder<ImplementationMethodDescriptor> implementationMethodsBuilder =\n        ImmutableSet.builder();\n    for (ExecutableElement implementationMethod :\n        ElementFilter.methodsIn(elements.getAllMembers(supertype))) {\n      if (implementationMethod.getModifiers().contains(Modifier.ABSTRACT)) {\n        ExecutableType methodType =\n            Elements2.getExecutableElementAsMemberOf(types, implementationMethod, supertype);\n        ImmutableSet<Parameter> passedParameters =\n            Parameter.forParameterList(\n                implementationMethod.getParameters(),\n                methodType.getParameterTypes(),\n                types,\n                injectApi);\n        implementationMethodsBuilder.add(\n            ImplementationMethodDescriptor.builder()\n                .name(implementationMethod.getSimpleName().toString())\n                .returnType(getAnnotatedType(autoFactoryElement))\n                .publicMethod()\n                .passedParameters(passedParameters)\n                .isVarArgs(implementationMethod.isVarArgs())\n                .exceptions(implementationMethod.getThrownTypes())\n                .build());\n      }\n    }\n    return implementationMethodsBuilder.build();\n  }\n\n  private TypeMirror getAnnotatedType(Element element) {\n    List<TypeElement> types = ImmutableList.of();\n    while (types.isEmpty()) {\n      types = ElementFilter.typesIn(Arrays.asList(element));\n      element = element.getEnclosingElement();\n    }\n    return Iterables.getOnlyElement(types).asType();\n  }\n\n  private static ImmutableSetMultimap<String, PackageAndClass> simpleNamesToNames(\n      ImmutableSet<PackageAndClass> names) {\n    // .collect(toImmutableSetMultimap(...)) would make this much simpler but ran into problems in\n    // Google's internal build system because of multiple Guava versions.\n    ImmutableSetMultimap.Builder<String, PackageAndClass> builder = ImmutableSetMultimap.builder();\n    for (PackageAndClass name : names) {\n      builder.put(name.className(), name);\n    }\n    return builder.build();\n  }\n\n  private static ImmutableSortedSet.Builder<TypeMirror> newTypeSetBuilder() {\n    return ImmutableSortedSet.orderedBy(\n        Comparator.comparing(t -> MoreTypes.asTypeElement(t).getQualifiedName().toString()));\n  }\n\n  /** Checks that {@link AnnotationsToApply} is used correctly. */\n  private void checkAnnotationsToApply(Element annotation) {\n    if (!annotation.getKind().equals(ANNOTATION_TYPE)) {\n      // Should not be possible because of @Target.\n      messager.printMessage(\n          Kind.ERROR,\n          \"@\"\n              + AnnotationsToApply.class.getSimpleName()\n              + \" must be applied to an annotation type declaration.\",\n          annotation);\n    }\n    Set<TypeElement> seenAnnotations = new HashSet<>();\n    for (ExecutableElement annotationMember : methodsIn(annotation.getEnclosedElements())) {\n      TypeMirror memberType = annotationMember.getReturnType();\n      boolean isAnnotation =\n          memberType.getKind().equals(DECLARED)\n              && asElement(memberType).getKind().equals(ANNOTATION_TYPE);\n      if (!isAnnotation && !memberType.getKind().equals(ERROR)) {\n        messager.printMessage(\n            Kind.ERROR,\n            \"Members of an @\"\n                + AnnotationsToApply.class.getSimpleName()\n                + \" annotation must themselves be annotations; \"\n                + annotationMember.getSimpleName()\n                + \" has type \"\n                + memberType,\n            annotationMember);\n      } else {\n        TypeElement annotationElement = asTypeElement(memberType);\n        if (!seenAnnotations.add(annotationElement)) {\n          messager.printMessage(\n              Kind.ERROR, \"More than one @\" + annotationElement + \" in \" + annotation, annotation);\n        }\n      }\n    }\n  }\n\n  @Override\n  public ImmutableSet<String> getSupportedAnnotationTypes() {\n    return ImmutableSet.of(\n        AutoFactory.class.getCanonicalName(),\n        Provided.class.getCanonicalName(),\n        AnnotationsToApply.class.getCanonicalName());\n  }\n\n  @Override\n  public SourceVersion getSupportedSourceVersion() {\n    return SourceVersion.latestSupported();\n  }\n}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/processor/Elements2.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport static com.google.common.base.Preconditions.checkArgument;\nimport static com.google.common.base.Preconditions.checkNotNull;\nimport static javax.lang.model.element.ElementKind.CLASS;\nimport static javax.lang.model.element.ElementKind.PACKAGE;\nimport static javax.lang.model.element.Modifier.FINAL;\nimport static javax.lang.model.element.Modifier.STATIC;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.common.collect.ImmutableSet;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.ExecutableType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.ElementFilter;\nimport javax.lang.model.util.Types;\n\nfinal class Elements2 {\n  private Elements2() {}\n\n  static ImmutableSet<ExecutableElement> getConstructors(TypeElement type) {\n    checkNotNull(type);\n    checkArgument(type.getKind() == CLASS);\n    return ImmutableSet.copyOf(ElementFilter.constructorsIn(type.getEnclosedElements()));\n  }\n\n  static boolean isValidSupertypeForClass(TypeElement type) {\n    if (!type.getKind().equals(CLASS)) {\n      return false;\n    }\n    if (type.getModifiers().contains(FINAL)) {\n      return false;\n    }\n    if (!type.getEnclosingElement().getKind().equals(PACKAGE)\n        && !type.getModifiers().contains(STATIC)) {\n      return false;\n    }\n    if (type.getSimpleName().length() == 0) {\n      return false;\n    }\n    return true;\n  }\n\n  /**\n   * Given an executable element in a supertype, returns its ExecutableType when it is viewed as a\n   * member of a subtype.\n   */\n  static ExecutableType getExecutableElementAsMemberOf(\n      Types types, ExecutableElement executableElement, TypeElement subTypeElement) {\n    checkNotNull(types);\n    checkNotNull(executableElement);\n    checkNotNull(subTypeElement);\n    TypeMirror subTypeMirror = subTypeElement.asType();\n    if (!subTypeMirror.getKind().equals(TypeKind.DECLARED)) {\n      throw new IllegalStateException(\n          \"Expected subTypeElement.asType() to return a class/interface type.\");\n    }\n    TypeMirror subExecutableTypeMirror =\n        types.asMemberOf(MoreTypes.asDeclared(subTypeMirror), executableElement);\n    if (!subExecutableTypeMirror.getKind().equals(TypeKind.EXECUTABLE)) {\n      throw new IllegalStateException(\"Expected subExecutableTypeMirror to be an executable type.\");\n    }\n    return MoreTypes.asExecutable(subExecutableTypeMirror);\n  }\n}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptor.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport com.google.auto.value.AutoValue;\nimport com.google.common.base.CharMatcher;\nimport com.google.common.collect.ImmutableBiMap;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.ImmutableSetMultimap;\nimport com.google.common.collect.Iterables;\nimport com.google.common.collect.Sets;\nimport com.google.common.collect.Streams;\nimport java.util.HashSet;\nimport java.util.Optional;\nimport java.util.Set;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.type.TypeMirror;\n\n/**\n * A value object representing a factory to be generated.\n *\n * @author Gregory Kick\n */\n@AutoValue\nabstract class FactoryDescriptor {\n  private static final CharMatcher INVALID_IDENTIFIER_CHARACTERS =\n      new CharMatcher() {\n        @Override\n        public boolean matches(char c) {\n          return !Character.isJavaIdentifierPart(c);\n        }\n      };\n\n  abstract PackageAndClass name();\n\n  abstract ImmutableSet<AnnotationMirror> annotations();\n\n  abstract TypeMirror extendingType();\n\n  abstract ImmutableSet<TypeMirror> implementingTypes();\n\n  abstract boolean publicType();\n\n  abstract ImmutableSet<FactoryMethodDescriptor> methodDescriptors();\n\n  abstract ImmutableSet<ImplementationMethodDescriptor> implementationMethodDescriptors();\n\n  abstract boolean allowSubclasses();\n\n  abstract ImmutableMap<Key, ProviderField> providers();\n\n  final AutoFactoryDeclaration declaration() {\n    // There is always at least one method descriptor.\n    return methodDescriptors().iterator().next().declaration();\n  }\n\n  private static class UniqueNameSet {\n    private final Set<String> uniqueNames = new HashSet<>();\n\n    /**\n     * Generates a unique name using {@code base}. If {@code base} has not yet been added, it will\n     * be returned as-is. If your {@code base} is healthy, this will always return {@code base}.\n     */\n    String getUniqueName(CharSequence base) {\n      String name = base.toString();\n      for (int differentiator = 2; !uniqueNames.add(name); differentiator++) {\n        name = base.toString() + differentiator;\n      }\n      return name;\n    }\n  }\n\n  static FactoryDescriptor create(\n      PackageAndClass name,\n      ImmutableSet<AnnotationMirror> annotations,\n      TypeMirror extendingType,\n      ImmutableSet<TypeMirror> implementingTypes,\n      boolean publicType,\n      ImmutableSet<FactoryMethodDescriptor> methodDescriptors,\n      ImmutableSet<ImplementationMethodDescriptor> implementationMethodDescriptors,\n      boolean allowSubclasses) {\n    ImmutableSetMultimap.Builder<Key, Parameter> parametersForProviders =\n        ImmutableSetMultimap.builder();\n    for (FactoryMethodDescriptor descriptor : methodDescriptors) {\n      for (Parameter parameter : descriptor.providedParameters()) {\n        parametersForProviders.put(parameter.key(), parameter);\n      }\n    }\n    ImmutableMap.Builder<Key, ProviderField> providersBuilder = ImmutableMap.builder();\n    UniqueNameSet uniqueNames = new UniqueNameSet();\n    parametersForProviders\n        .build()\n        .asMap()\n        .forEach(\n            (key, parameters) -> {\n              switch (parameters.size()) {\n                case 0:\n                  throw new AssertionError();\n                case 1:\n                  Parameter parameter = Iterables.getOnlyElement(parameters);\n                  providersBuilder.put(\n                      key,\n                      ProviderField.create(\n                          uniqueNames.getUniqueName(parameter.name() + \"Provider\"),\n                          key,\n                          parameter.nullable()));\n                  break;\n                default:\n                  String providerName =\n                      uniqueNames.getUniqueName(\n                          INVALID_IDENTIFIER_CHARACTERS.replaceFrom(key.toString(), '_')\n                              + \"Provider\");\n                  Optional<AnnotationMirror> nullable =\n                      parameters.stream()\n                          .map(Parameter::nullable)\n                          .flatMap(Streams::stream)\n                          .findFirst();\n                  providersBuilder.put(key, ProviderField.create(providerName, key, nullable));\n                  break;\n              }\n            });\n\n    ImmutableBiMap<FactoryMethodDescriptor, ImplementationMethodDescriptor>\n        duplicateMethodDescriptors =\n            createDuplicateMethodDescriptorsBiMap(\n                methodDescriptors, implementationMethodDescriptors);\n\n    ImmutableSet<FactoryMethodDescriptor> deduplicatedMethodDescriptors =\n        getDeduplicatedMethodDescriptors(methodDescriptors, duplicateMethodDescriptors);\n\n    ImmutableSet<ImplementationMethodDescriptor> deduplicatedImplementationMethodDescriptors =\n        Sets.difference(implementationMethodDescriptors, duplicateMethodDescriptors.values())\n            .immutableCopy();\n\n    return new AutoValue_FactoryDescriptor(\n        name,\n        annotations,\n        extendingType,\n        implementingTypes,\n        publicType,\n        deduplicatedMethodDescriptors,\n        deduplicatedImplementationMethodDescriptors,\n        allowSubclasses,\n        providersBuilder.build());\n  }\n\n  /**\n   * Creates a bi-map of duplicate {@link ImplementationMethodDescriptor}s by their respective\n   * {@link FactoryMethodDescriptor}.\n   */\n  private static ImmutableBiMap<FactoryMethodDescriptor, ImplementationMethodDescriptor>\n      createDuplicateMethodDescriptorsBiMap(\n          ImmutableSet<FactoryMethodDescriptor> factoryMethodDescriptors,\n          ImmutableSet<ImplementationMethodDescriptor> implementationMethodDescriptors) {\n\n    ImmutableBiMap.Builder<FactoryMethodDescriptor, ImplementationMethodDescriptor> builder =\n        ImmutableBiMap.builder();\n\n    for (FactoryMethodDescriptor factoryMethodDescriptor : factoryMethodDescriptors) {\n      for (ImplementationMethodDescriptor implementationMethodDescriptor :\n          implementationMethodDescriptors) {\n\n        boolean areDuplicateMethodDescriptors =\n            areDuplicateMethodDescriptors(factoryMethodDescriptor, implementationMethodDescriptor);\n        if (areDuplicateMethodDescriptors) {\n          builder.put(factoryMethodDescriptor, implementationMethodDescriptor);\n          break;\n        }\n      }\n    }\n\n    return builder.build();\n  }\n\n  /**\n   * Returns a set of deduplicated {@link FactoryMethodDescriptor}s from the set of original\n   * descriptors and the bi-map of duplicate descriptors.\n   *\n   * <p>Modifies the duplicate {@link FactoryMethodDescriptor}s such that they are overriding and\n   * reflect properties from the {@link ImplementationMethodDescriptor} they are implementing.\n   */\n  private static ImmutableSet<FactoryMethodDescriptor> getDeduplicatedMethodDescriptors(\n      ImmutableSet<FactoryMethodDescriptor> methodDescriptors,\n      ImmutableBiMap<FactoryMethodDescriptor, ImplementationMethodDescriptor>\n          duplicateMethodDescriptors) {\n\n    ImmutableSet.Builder<FactoryMethodDescriptor> deduplicatedMethodDescriptors =\n        ImmutableSet.builder();\n\n    for (FactoryMethodDescriptor methodDescriptor : methodDescriptors) {\n      ImplementationMethodDescriptor duplicateMethodDescriptor =\n          duplicateMethodDescriptors.get(methodDescriptor);\n\n      FactoryMethodDescriptor newMethodDescriptor =\n          (duplicateMethodDescriptor != null)\n              ? methodDescriptor.toBuilder()\n                  .overridingMethod(true)\n                  .publicMethod(duplicateMethodDescriptor.publicMethod())\n                  .returnType(duplicateMethodDescriptor.returnType())\n                  .exceptions(duplicateMethodDescriptor.exceptions())\n                  .build()\n              : methodDescriptor;\n      deduplicatedMethodDescriptors.add(newMethodDescriptor);\n    }\n\n    return deduplicatedMethodDescriptors.build();\n  }\n\n  /**\n   * Returns true if the given {@link FactoryMethodDescriptor} and {@link\n   * ImplementationMethodDescriptor} are duplicates.\n   *\n   * <p>Descriptors are duplicates if they have the same name and if they have the same passed types\n   * in the same order.\n   */\n  private static boolean areDuplicateMethodDescriptors(\n      FactoryMethodDescriptor factory, ImplementationMethodDescriptor implementation) {\n\n    if (!factory.name().equals(implementation.name())) {\n      return false;\n    }\n\n    // Descriptors are identical if they have the same passed types in the same order.\n    return Iterables.elementsEqual(\n        Iterables.transform(factory.passedParameters(), Parameter::type),\n        Iterables.transform(implementation.passedParameters(), Parameter::type));\n  }\n}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptorGenerator.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport static com.google.auto.common.MoreElements.isAnnotationPresent;\nimport static com.google.common.base.Preconditions.checkArgument;\nimport static com.google.common.base.Preconditions.checkNotNull;\nimport static java.util.Objects.requireNonNull;\nimport static java.util.stream.Collectors.partitioningBy;\nimport static javax.lang.model.element.Modifier.ABSTRACT;\nimport static javax.lang.model.element.Modifier.PUBLIC;\nimport static javax.tools.Diagnostic.Kind.ERROR;\n\nimport com.google.auto.common.MoreElements;\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.Provided;\nimport com.google.common.base.Function;\nimport com.google.common.collect.FluentIterable;\nimport com.google.common.collect.ImmutableSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport javax.annotation.processing.Messager;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ElementKind;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.util.ElementKindVisitor6;\nimport javax.lang.model.util.Types;\n\n/**\n * A service that traverses an element and returns the set of factory methods defined therein.\n *\n * @author Gregory Kick\n */\nfinal class FactoryDescriptorGenerator {\n  private final Messager messager;\n  private final Types types;\n  private final AutoFactoryDeclaration.Factory declarationFactory;\n  private final InjectApi injectApi;\n\n  FactoryDescriptorGenerator(\n      Messager messager,\n      Types types,\n      AutoFactoryDeclaration.Factory declarationFactory,\n      InjectApi injectApi) {\n    this.messager = messager;\n    this.types = types;\n    this.declarationFactory = declarationFactory;\n    this.injectApi = injectApi;\n  }\n\n  ImmutableSet<FactoryMethodDescriptor> generateDescriptor(Element element) {\n    final AnnotationMirror mirror = Mirrors.getAnnotationMirror(element, AutoFactory.class).get();\n    final Optional<AutoFactoryDeclaration> declaration = declarationFactory.createIfValid(element);\n    if (!declaration.isPresent()) {\n      return ImmutableSet.of();\n    }\n    return element.accept(\n        new ElementKindVisitor6<ImmutableSet<FactoryMethodDescriptor>, Void>() {\n          @Override\n          protected ImmutableSet<FactoryMethodDescriptor> defaultAction(Element e, Void p) {\n            throw new AssertionError(\"@AutoFactory applied to an impossible element\");\n          }\n\n          @Override\n          public ImmutableSet<FactoryMethodDescriptor> visitTypeAsClass(TypeElement type, Void p) {\n            if (type.getModifiers().contains(ABSTRACT)) {\n              // applied to an abstract factory\n              messager.printMessage(\n                  ERROR,\n                  \"Auto-factory doesn't support being applied to abstract classes.\",\n                  type,\n                  mirror);\n              return ImmutableSet.of();\n            } else {\n              // applied to the type to be created\n              ImmutableSet<ExecutableElement> constructors = Elements2.getConstructors(type);\n              if (constructors.isEmpty()) {\n                return generateDescriptorForDefaultConstructor(declaration.get(), type);\n              } else {\n                return FluentIterable.from(constructors)\n                    .transform(\n                        new Function<ExecutableElement, FactoryMethodDescriptor>() {\n                          @Override\n                          public FactoryMethodDescriptor apply(ExecutableElement constructor) {\n                            return generateDescriptorForConstructor(declaration.get(), constructor);\n                          }\n                        })\n                    .toSet();\n              }\n            }\n          }\n\n          @Override\n          public ImmutableSet<FactoryMethodDescriptor> visitTypeAsInterface(\n              TypeElement type, Void p) {\n            // applied to the factory interface\n            messager.printMessage(\n                ERROR, \"Auto-factory doesn't support being applied to interfaces.\", type, mirror);\n            return ImmutableSet.of();\n          }\n\n          @Override\n          public ImmutableSet<FactoryMethodDescriptor> visitExecutableAsConstructor(\n              ExecutableElement e, Void p) {\n            // applied to a constructor of a type to be created\n            return ImmutableSet.of(generateDescriptorForConstructor(declaration.get(), e));\n          }\n        },\n        null);\n  }\n\n  FactoryMethodDescriptor generateDescriptorForConstructor(\n      final AutoFactoryDeclaration declaration, ExecutableElement constructor) {\n    checkNotNull(constructor);\n    checkArgument(constructor.getKind() == ElementKind.CONSTRUCTOR);\n    TypeElement classElement = MoreElements.asType(constructor.getEnclosingElement());\n    Map<Boolean, List<VariableElement>> parameterMap =\n        constructor.getParameters().stream()\n            .collect(partitioningBy(parameter -> isAnnotationPresent(parameter, Provided.class)));\n    // The map returned by partitioningBy always has entries for both key values but our\n    // null-checker isn't yet smart enough to know that.\n    ImmutableSet<Parameter> providedParameters =\n        Parameter.forParameterList(requireNonNull(parameterMap.get(true)), types, injectApi);\n    ImmutableSet<Parameter> passedParameters =\n        Parameter.forParameterList(requireNonNull(parameterMap.get(false)), types, injectApi);\n    return FactoryMethodDescriptor.builder(declaration)\n        .name(\"create\")\n        .returnType(classElement.asType())\n        .publicMethod(classElement.getModifiers().contains(PUBLIC))\n        .providedParameters(providedParameters)\n        .passedParameters(passedParameters)\n        .creationParameters(\n            Parameter.forParameterList(constructor.getParameters(), types, injectApi))\n        .isVarArgs(constructor.isVarArgs())\n        .exceptions(constructor.getThrownTypes())\n        .overridingMethod(false)\n        .build();\n  }\n\n  private ImmutableSet<FactoryMethodDescriptor> generateDescriptorForDefaultConstructor(\n      AutoFactoryDeclaration declaration, TypeElement type) {\n    return ImmutableSet.of(\n        FactoryMethodDescriptor.builder(declaration)\n            .name(\"create\")\n            .returnType(type.asType())\n            .publicMethod(type.getModifiers().contains(PUBLIC))\n            .providedParameters(ImmutableSet.of())\n            .passedParameters(ImmutableSet.of())\n            .creationParameters(ImmutableSet.of())\n            .isVarArgs(false)\n            .exceptions(ImmutableSet.of())\n            .overridingMethod(false)\n            .build());\n  }\n}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/processor/FactoryMethodDescriptor.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport static com.google.common.base.Preconditions.checkNotNull;\nimport static com.google.common.base.Preconditions.checkState;\n\nimport com.google.auto.value.AutoValue;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Sets;\nimport javax.lang.model.type.TypeMirror;\n\n/**\n * A value object representing a factory method to be generated.\n *\n * @author Gregory Kick\n */\n@AutoValue\nabstract class FactoryMethodDescriptor {\n  abstract AutoFactoryDeclaration declaration();\n\n  abstract String name();\n\n  abstract TypeMirror returnType();\n\n  abstract boolean publicMethod();\n\n  abstract boolean overridingMethod();\n\n  /** The parameters that are passed to the {@code create} method. */\n  abstract ImmutableSet<Parameter> passedParameters();\n\n  /**\n   * The factory constructor parameters that this factory method requires. When there is more than\n   * one AutoFactory constructor, each one can have its own {@code @Provided} parameters, or\n   * constructors can have {@code @Provided} parameters in common. The generated factory has a\n   * single constructor, which has one {@code @Injected} constructor parameter for each unique\n   * {@code @Provided} parameter in any constructor.\n   */\n  abstract ImmutableSet<Parameter> providedParameters();\n\n  /**\n   * The parameters of the constructor that this {@code create} method calls. This is the union of\n   * {@link #passedParameters()} and {@link #providedParameters()}.\n   */\n  abstract ImmutableSet<Parameter> creationParameters();\n\n  abstract boolean isVarArgs();\n\n  abstract ImmutableSet<TypeMirror> exceptions();\n\n  abstract Builder toBuilder();\n\n  final PackageAndClass factoryName() {\n    return declaration().getFactoryName();\n  }\n\n  static Builder builder(AutoFactoryDeclaration declaration) {\n    return new AutoValue_FactoryMethodDescriptor.Builder().declaration(checkNotNull(declaration));\n  }\n\n  @AutoValue.Builder\n  abstract static class Builder {\n    abstract Builder declaration(AutoFactoryDeclaration declaration);\n\n    abstract Builder name(String name);\n\n    abstract Builder returnType(TypeMirror returnType);\n\n    abstract Builder publicMethod(boolean publicMethod);\n\n    abstract Builder overridingMethod(boolean overridingMethod);\n\n    abstract Builder passedParameters(Iterable<Parameter> passedParameters);\n\n    abstract Builder providedParameters(Iterable<Parameter> providedParameters);\n\n    abstract Builder creationParameters(Iterable<Parameter> creationParameters);\n\n    abstract Builder isVarArgs(boolean isVarargs);\n\n    abstract Builder exceptions(Iterable<? extends TypeMirror> exceptions);\n\n    abstract FactoryMethodDescriptor buildImpl();\n\n    FactoryMethodDescriptor build() {\n      FactoryMethodDescriptor descriptor = buildImpl();\n      checkState(\n          descriptor\n              .creationParameters()\n              .equals(Sets.union(descriptor.passedParameters(), descriptor.providedParameters())));\n      return descriptor;\n    }\n  }\n}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/processor/FactoryWriter.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport static com.google.auto.common.GeneratedAnnotationSpecs.generatedAnnotationSpec;\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static com.squareup.javapoet.MethodSpec.constructorBuilder;\nimport static com.squareup.javapoet.MethodSpec.methodBuilder;\nimport static com.squareup.javapoet.TypeSpec.classBuilder;\nimport static java.util.Objects.requireNonNull;\nimport static java.util.stream.Collectors.joining;\nimport static java.util.stream.Collectors.toList;\nimport static javax.lang.model.element.Modifier.FINAL;\nimport static javax.lang.model.element.Modifier.PRIVATE;\nimport static javax.lang.model.element.Modifier.PUBLIC;\nimport static javax.lang.model.element.Modifier.STATIC;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.common.collect.ImmutableCollection;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.ImmutableSetMultimap;\nimport com.google.common.collect.Iterables;\nimport com.google.common.collect.Sets;\nimport com.squareup.javapoet.AnnotationSpec;\nimport com.squareup.javapoet.ClassName;\nimport com.squareup.javapoet.CodeBlock;\nimport com.squareup.javapoet.JavaFile;\nimport com.squareup.javapoet.MethodSpec;\nimport com.squareup.javapoet.ParameterSpec;\nimport com.squareup.javapoet.ParameterizedTypeName;\nimport com.squareup.javapoet.TypeName;\nimport com.squareup.javapoet.TypeSpec;\nimport com.squareup.javapoet.TypeVariableName;\nimport java.io.IOException;\nimport java.util.List;\nimport javax.annotation.processing.Filer;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.type.TypeVariable;\nimport javax.lang.model.util.Elements;\n\nfinal class FactoryWriter {\n\n  private final InjectApi injectApi;\n  private final Filer filer;\n  private final Elements elements;\n  private final SourceVersion sourceVersion;\n  private final ImmutableSetMultimap<String, PackageAndClass> factoriesBeingCreated;\n\n  FactoryWriter(\n      ProcessingEnvironment processingEnv,\n      InjectApi injectApi,\n      ImmutableSetMultimap<String, PackageAndClass> factoriesBeingCreated) {\n    this.injectApi = injectApi;\n    this.filer = processingEnv.getFiler();\n    this.elements = processingEnv.getElementUtils();\n    this.sourceVersion = processingEnv.getSourceVersion();\n    this.factoriesBeingCreated = factoriesBeingCreated;\n  }\n\n  void writeFactory(FactoryDescriptor descriptor) throws IOException {\n    String factoryName = descriptor.name().className();\n    TypeSpec.Builder factory =\n        classBuilder(factoryName).addOriginatingElement(descriptor.declaration().targetType());\n    generatedAnnotationSpec(\n            elements,\n            sourceVersion,\n            AutoFactoryProcessor.class,\n            \"https://github.com/google/auto/tree/main/factory\")\n        .ifPresent(factory::addAnnotation);\n    descriptor.annotations().forEach(a -> factory.addAnnotation(AnnotationSpec.get(a)));\n    if (!descriptor.allowSubclasses()) {\n      factory.addModifiers(FINAL);\n    }\n    if (descriptor.publicType()) {\n      factory.addModifiers(PUBLIC);\n    }\n\n    factory.superclass(TypeName.get(descriptor.extendingType()));\n    for (TypeMirror implementingType : descriptor.implementingTypes()) {\n      factory.addSuperinterface(TypeName.get(implementingType));\n    }\n\n    ImmutableSet<TypeVariableName> factoryTypeVariables = getFactoryTypeVariables(descriptor);\n\n    addFactoryTypeParameters(factory, factoryTypeVariables);\n    addConstructorAndProviderFields(factory, descriptor);\n    addFactoryMethods(factory, descriptor, factoryTypeVariables);\n    addImplementationMethods(factory, descriptor);\n    addCheckNotNullMethod(factory, descriptor);\n\n    JavaFile.builder(descriptor.name().packageName(), factory.build())\n        .skipJavaLangImports(true)\n        .build()\n        .writeTo(filer);\n  }\n\n  private static void addFactoryTypeParameters(\n      TypeSpec.Builder factory, ImmutableSet<TypeVariableName> typeVariableNames) {\n    factory.addTypeVariables(typeVariableNames);\n  }\n\n  private void addConstructorAndProviderFields(\n      TypeSpec.Builder factory, FactoryDescriptor descriptor) {\n    MethodSpec.Builder constructor =\n        constructorBuilder().addAnnotation(ClassName.get(injectApi.inject()));\n    if (descriptor.publicType()) {\n      constructor.addModifiers(PUBLIC);\n    }\n    ImmutableCollection<ProviderField> providerFields = descriptor.providers().values();\n    int argumentNumber = 0;\n    for (ProviderField provider : providerFields) {\n      ++argumentNumber;\n      TypeName typeName = resolveTypeName(provider.key().type().get()).box();\n      TypeName providerType =\n          ParameterizedTypeName.get(ClassName.get(injectApi.provider()), typeName);\n      factory.addField(providerType, provider.name(), PRIVATE, FINAL);\n      if (provider.key().qualifier().isPresent()) {\n        // only qualify the constructor parameter\n        providerType = providerType.annotated(AnnotationSpec.get(provider.key().qualifier().get()));\n      }\n      constructor.addParameter(providerType, provider.name());\n      constructor.addStatement(\n          \"this.$1L = checkNotNull($1L, $2L, $3L)\",\n          provider.name(),\n          argumentNumber,\n          providerFields.size());\n    }\n\n    factory.addMethod(constructor.build());\n  }\n\n  private void addFactoryMethods(\n      TypeSpec.Builder factory,\n      FactoryDescriptor descriptor,\n      ImmutableSet<TypeVariableName> factoryTypeVariables) {\n    for (FactoryMethodDescriptor methodDescriptor : descriptor.methodDescriptors()) {\n      MethodSpec.Builder method =\n          methodBuilder(methodDescriptor.name())\n              .addTypeVariables(getMethodTypeVariables(methodDescriptor, factoryTypeVariables))\n              .returns(TypeName.get(methodDescriptor.returnType()))\n              .varargs(methodDescriptor.isVarArgs());\n      if (methodDescriptor.overridingMethod()) {\n        method.addAnnotation(Override.class);\n      }\n      if (methodDescriptor.publicMethod()) {\n        method.addModifiers(PUBLIC);\n      }\n      method.addExceptions(\n          methodDescriptor.exceptions().stream().map(TypeName::get).collect(toList()));\n      CodeBlock.Builder args = CodeBlock.builder();\n      method.addParameters(parameters(methodDescriptor.passedParameters()));\n      ImmutableSet<Parameter> parameters = methodDescriptor.creationParameters();\n      int argumentNumber = 0;\n      String sep = \"\";\n      for (Parameter parameter : parameters) {\n        ++argumentNumber;\n        args.add(sep);\n        sep = \", \";\n        boolean checkNotNull = !parameter.nullable().isPresent();\n        CodeBlock argument;\n        if (methodDescriptor.passedParameters().contains(parameter)) {\n          argument = CodeBlock.of(parameter.name());\n          if (parameter.isPrimitive()) {\n            checkNotNull = false;\n          }\n        } else {\n          ProviderField provider = requireNonNull(descriptor.providers().get(parameter.key()));\n          argument = CodeBlock.of(provider.name());\n          if (injectApi.isProvider(parameter.type().get())) {\n            // Providers are checked for nullness in the Factory's constructor.\n            checkNotNull = false;\n          } else {\n            argument = CodeBlock.of(\"$L.get()\", argument);\n          }\n        }\n        if (checkNotNull) {\n          argument =\n              CodeBlock.of(\"checkNotNull($L, $L, $L)\", argument, argumentNumber, parameters.size());\n        }\n        args.add(argument);\n      }\n      method.addStatement(\"return new $T($L)\", methodDescriptor.returnType(), args.build());\n      factory.addMethod(method.build());\n    }\n  }\n\n  private void addImplementationMethods(TypeSpec.Builder factory, FactoryDescriptor descriptor) {\n    for (ImplementationMethodDescriptor methodDescriptor :\n        descriptor.implementationMethodDescriptors()) {\n      MethodSpec.Builder implementationMethod =\n          methodBuilder(methodDescriptor.name())\n              .addAnnotation(Override.class)\n              .returns(TypeName.get(methodDescriptor.returnType()))\n              .varargs(methodDescriptor.isVarArgs());\n      if (methodDescriptor.publicMethod()) {\n        implementationMethod.addModifiers(PUBLIC);\n      }\n      implementationMethod.addExceptions(\n          methodDescriptor.exceptions().stream().map(TypeName::get).collect(toList()));\n      implementationMethod.addParameters(parameters(methodDescriptor.passedParameters()));\n      implementationMethod.addStatement(\n          \"return create($L)\",\n          methodDescriptor.passedParameters().stream().map(Parameter::name).collect(joining(\", \")));\n      factory.addMethod(implementationMethod.build());\n    }\n  }\n\n  /**\n   * {@link ParameterSpec}s to match {@code parameters}. Note that the type of the {@link\n   * ParameterSpec}s match {@link Parameter#type()} and not {@link Key#type()}.\n   */\n  private ImmutableList<ParameterSpec> parameters(Iterable<Parameter> parameters) {\n    ImmutableList.Builder<ParameterSpec> builder = ImmutableList.builder();\n    for (Parameter parameter : parameters) {\n      TypeName type = resolveTypeName(parameter.type().get());\n      ImmutableList<AnnotationSpec> annotations =\n          parameter.annotations().stream().map(AnnotationSpec::get).collect(toImmutableList());\n      ParameterSpec parameterSpec =\n          ParameterSpec.builder(type, parameter.name()).addAnnotations(annotations).build();\n      builder.add(parameterSpec);\n    }\n    return builder.build();\n  }\n\n  private static void addCheckNotNullMethod(\n      TypeSpec.Builder factory, FactoryDescriptor descriptor) {\n    if (shouldGenerateCheckNotNull(descriptor)) {\n      TypeVariableName typeVariable = TypeVariableName.get(\"T\");\n      factory.addMethod(\n          methodBuilder(\"checkNotNull\")\n              .addModifiers(PRIVATE, STATIC)\n              .addTypeVariable(typeVariable)\n              .returns(typeVariable)\n              .addParameter(typeVariable, \"reference\")\n              .addParameter(TypeName.INT, \"argumentNumber\")\n              .addParameter(TypeName.INT, \"argumentCount\")\n              .beginControlFlow(\"if (reference == null)\")\n              .addStatement(\n                  \"throw new $T($S + argumentNumber + $S + argumentCount)\",\n                  NullPointerException.class,\n                  \"@AutoFactory method argument is null but is not marked @Nullable. Argument \",\n                  \" of \")\n              .endControlFlow()\n              .addStatement(\"return reference\")\n              .build());\n    }\n  }\n\n  private static boolean shouldGenerateCheckNotNull(FactoryDescriptor descriptor) {\n    if (!descriptor.providers().isEmpty()) {\n      return true;\n    }\n    for (FactoryMethodDescriptor method : descriptor.methodDescriptors()) {\n      for (Parameter parameter : method.creationParameters()) {\n        if (!parameter.nullable().isPresent() && !parameter.type().get().getKind().isPrimitive()) {\n          return true;\n        }\n      }\n    }\n    return false;\n  }\n\n  /**\n   * Returns an appropriate {@code TypeName} for the given type. If the type is an {@code\n   * ErrorType}, and if it is a simple-name reference to one of the {@code *Factory} classes that we\n   * are going to generate, then we return its fully-qualified name. In every other case we just\n   * return {@code TypeName.get(type)}. Specifically, if it is an {@code ErrorType} referencing some\n   * other type, or referencing one of the classes we are going to generate but using its\n   * fully-qualified name, then we leave it as-is. JavaPoet treats {@code TypeName.get(t)} the same\n   * for {@code ErrorType} as for {@code DeclaredType}, which means that if this is a name that will\n   * eventually be generated then the code we write that references the type will in fact compile.\n   *\n   * <p>A simpler alternative would be to defer processing to a later round if we find an\n   * {@code @AutoFactory} class that references undefined types, under the assumption that something\n   * else will generate those types in the meanwhile. However, this would fail if for example\n   * {@code @AutoFactory class Foo} has a constructor parameter of type {@code BarFactory} and\n   * {@code @AutoFactory class Bar} has a constructor parameter of type {@code FooFactory}. We did\n   * in fact find instances of this in Google's source base.\n   *\n   * <p>If the type has type annotations then include those in the returned {@link TypeName}.\n   */\n  private TypeName resolveTypeName(TypeMirror type) {\n    TypeName typeName = TypeName.get(type);\n    if (type.getKind() == TypeKind.ERROR) {\n      ImmutableSet<PackageAndClass> factoryNames = factoriesBeingCreated.get(type.toString());\n      if (factoryNames.size() == 1) {\n        PackageAndClass packageAndClass = Iterables.getOnlyElement(factoryNames);\n        typeName = ClassName.get(packageAndClass.packageName(), packageAndClass.className());\n      }\n    }\n    return typeName.annotated(\n        type.getAnnotationMirrors().stream().map(AnnotationSpec::get).collect(toList()));\n  }\n\n  private static ImmutableSet<TypeVariableName> getFactoryTypeVariables(\n      FactoryDescriptor descriptor) {\n    ImmutableSet.Builder<TypeVariableName> typeVariables = ImmutableSet.builder();\n    for (ProviderField provider : descriptor.providers().values()) {\n      typeVariables.addAll(getReferencedTypeParameterNames(provider.key().type().get()));\n    }\n    // If a parent type has a type parameter, like FooFactory<T>, then the generated factory needs\n    // to have the same parameter, like FooImplFactory<T> extends FooFactory<T>. This is a little\n    // approximate, at least in the case where there is more than one parent type that has a type\n    // parameter. But that should be pretty rare, so let's keep it simple for now.\n    typeVariables.addAll(typeVariablesFrom(descriptor.extendingType()));\n    for (TypeMirror implementing : descriptor.implementingTypes()) {\n      typeVariables.addAll(typeVariablesFrom(implementing));\n    }\n    return typeVariables.build();\n  }\n\n  private static List<TypeVariableName> typeVariablesFrom(TypeMirror type) {\n    if (type.getKind().equals(TypeKind.DECLARED)) {\n      DeclaredType declaredType = MoreTypes.asDeclared(type);\n      return declaredType.getTypeArguments().stream()\n          .filter(t -> t.getKind().equals(TypeKind.TYPEVAR))\n          .map(t -> TypeVariableName.get(MoreTypes.asTypeVariable(t)))\n          .collect(toList());\n    }\n    return ImmutableList.of();\n  }\n\n  private static ImmutableSet<TypeVariableName> getMethodTypeVariables(\n      FactoryMethodDescriptor methodDescriptor,\n      ImmutableSet<TypeVariableName> factoryTypeVariables) {\n    ImmutableSet.Builder<TypeVariableName> typeVariables = ImmutableSet.builder();\n    typeVariables.addAll(getReferencedTypeParameterNames(methodDescriptor.returnType()));\n    for (Parameter parameter : methodDescriptor.passedParameters()) {\n      typeVariables.addAll(getReferencedTypeParameterNames(parameter.type().get()));\n    }\n    return Sets.difference(typeVariables.build(), factoryTypeVariables).immutableCopy();\n  }\n\n  private static ImmutableSet<TypeVariableName> getReferencedTypeParameterNames(TypeMirror type) {\n    ImmutableSet.Builder<TypeVariableName> typeVariableNames = ImmutableSet.builder();\n    for (TypeVariable typeVariable : TypeVariables.getReferencedTypeVariables(type)) {\n      typeVariableNames.add(TypeVariableName.get(typeVariable));\n    }\n    return typeVariableNames.build();\n  }\n}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/processor/ImplementationMethodDescriptor.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport com.google.auto.value.AutoValue;\nimport com.google.common.collect.ImmutableSet;\nimport javax.lang.model.type.TypeMirror;\n\n@AutoValue\nabstract class ImplementationMethodDescriptor {\n  abstract String name();\n\n  abstract TypeMirror returnType();\n\n  abstract boolean publicMethod();\n\n  abstract ImmutableSet<Parameter> passedParameters();\n\n  abstract boolean isVarArgs();\n\n  abstract ImmutableSet<TypeMirror> exceptions();\n\n  static Builder builder() {\n    return new AutoValue_ImplementationMethodDescriptor.Builder();\n  }\n\n  @AutoValue.Builder\n  abstract static class Builder {\n    abstract Builder name(String name);\n\n    abstract Builder returnType(TypeMirror returnTypeElement);\n\n    abstract Builder publicMethod(boolean publicMethod);\n\n    final Builder publicMethod() {\n      return publicMethod(true);\n    }\n\n    abstract Builder passedParameters(Iterable<Parameter> passedParameters);\n\n    abstract Builder isVarArgs(boolean isVarargs);\n\n    abstract Builder exceptions(Iterable<? extends TypeMirror> exceptions);\n\n    abstract ImplementationMethodDescriptor build();\n  }\n}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/processor/InjectApi.java",
    "content": "/*\n * Copyright 2023 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport static com.google.common.collect.ImmutableMap.toImmutableMap;\nimport static java.util.stream.Collectors.joining;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.value.AutoValue;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport java.util.AbstractMap.SimpleEntry;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.Elements;\nimport org.jspecify.annotations.Nullable;\n\n/** Encapsulates the choice of {@code jakarta.inject} or {@code javax.inject}. */\n@AutoValue\nabstract class InjectApi {\n  abstract TypeElement inject();\n\n  abstract TypeElement provider();\n\n  abstract TypeElement qualifier();\n\n  private static final ImmutableList<String> PREFIXES_IN_ORDER =\n      ImmutableList.of(\"jakarta.inject.\", \"javax.inject.\");\n\n  static InjectApi from(Elements elementUtils, @Nullable String apiPrefix) {\n    ImmutableList<String> apiPackages =\n        (apiPrefix == null) ? PREFIXES_IN_ORDER : ImmutableList.of(apiPrefix + \".inject.\");\n    for (String apiPackage : apiPackages) {\n      ImmutableMap<String, TypeElement> apiMap = apiMap(elementUtils, apiPackage);\n      TypeElement inject = apiMap.get(\"Inject\");\n      TypeElement provider = apiMap.get(\"Provider\");\n      TypeElement qualifier = apiMap.get(\"Qualifier\");\n      if (inject != null && provider != null && qualifier != null) {\n        return new AutoValue_InjectApi(inject, provider, qualifier);\n      }\n    }\n    String classes = \"{\" + String.join(\",\", API_CLASSES) + \"}\";\n    String missing = apiPackages.stream().sorted().map(s -> s + classes).collect(joining(\" or \"));\n    throw new IllegalStateException(\"Class path for AutoFactory class must include \" + missing);\n  }\n\n  /** True if {@code type} is a {@code Provider}. */\n  boolean isProvider(TypeMirror type) {\n    return type.getKind().equals(TypeKind.DECLARED)\n        && MoreTypes.asTypeElement(type).equals(provider());\n  }\n\n  private static ImmutableMap<String, TypeElement> apiMap(\n      Elements elementUtils, String apiPackage) {\n    return API_CLASSES.stream()\n        .map(name -> new SimpleEntry<>(name, elementUtils.getTypeElement(apiPackage + name)))\n        .filter(entry -> entry.getValue() != null)\n        .collect(toImmutableMap(SimpleEntry::getKey, SimpleEntry::getValue));\n  }\n\n  private static final ImmutableSet<String> API_CLASSES =\n      ImmutableSet.of(\"Inject\", \"Provider\", \"Qualifier\");\n}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/processor/Key.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport static com.google.auto.common.MoreElements.isAnnotationPresent;\nimport static com.google.auto.factory.processor.Mirrors.unwrapOptionalEquivalence;\nimport static com.google.auto.factory.processor.Mirrors.wrapOptionalInEquivalence;\n\nimport com.google.auto.common.AnnotationMirrors;\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.value.AutoValue;\nimport com.google.common.base.Equivalence;\nimport java.util.Collection;\nimport java.util.Optional;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.Types;\n\n/**\n * A value object for types and qualifiers.\n *\n * @author Gregory Kick\n */\n@AutoValue\nabstract class Key {\n\n  abstract Equivalence.Wrapper<TypeMirror> type();\n\n  abstract Optional<Equivalence.Wrapper<AnnotationMirror>> qualifierWrapper();\n\n  Optional<AnnotationMirror> qualifier() {\n    return unwrapOptionalEquivalence(qualifierWrapper());\n  }\n\n  /**\n   * Constructs a key based on the type {@code type} and any {@code Qualifier}s in {@code\n   * annotations}.\n   *\n   * <p>If {@code type} is a {@code Provider<T>}, the returned {@link Key}'s {@link #type()} is\n   * {@code T}. If {@code type} is a primitive, the returned {@link Key}'s {@link #type()} is the\n   * corresponding {@linkplain Types#boxedClass(PrimitiveType) boxed type}.\n   *\n   * <p>For example:\n   *\n   * <table>\n   *   <tr><th>Input type                <th>{@code Key.type()}\n   *   <tr><td>{@code String}            <td>{@code String}\n   *   <tr><td>{@code Provider<String>}  <td>{@code String}\n   *   <tr><td>{@code int}               <td>{@code Integer}\n   * </table>\n   */\n  static Key create(\n      TypeMirror type, Collection<AnnotationMirror> annotations, Types types, InjectApi injectApi) {\n    // TODO(gak): check for only one qualifier rather than using the first\n    Optional<AnnotationMirror> qualifier =\n        annotations.stream()\n            .filter(\n                annotation ->\n                    isAnnotationPresent(\n                        annotation.getAnnotationType().asElement(), injectApi.qualifier()))\n            .findFirst();\n\n    TypeMirror keyType =\n        injectApi.isProvider(type)\n            ? MoreTypes.asDeclared(type).getTypeArguments().get(0)\n            : boxedType(type, types);\n    return new AutoValue_Key(\n        MoreTypes.equivalence().wrap(keyType),\n        wrapOptionalInEquivalence(AnnotationMirrors.equivalence(), qualifier));\n  }\n\n  /**\n   * If {@code type} is a primitive type, returns the boxed equivalent; otherwise returns {@code\n   * type}.\n   */\n  private static TypeMirror boxedType(TypeMirror type, Types types) {\n    return type.getKind().isPrimitive()\n        ? types.boxedClass(MoreTypes.asPrimitiveType(type)).asType()\n        : type;\n  }\n\n  @Override\n  public final String toString() {\n    String typeQualifiedName = MoreTypes.asTypeElement(type().get()).toString();\n    return qualifier().isPresent()\n        ? AnnotationMirrors.toString(qualifier().get()) + \"/\" + typeQualifiedName\n        : typeQualifiedName;\n  }\n}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/processor/Mirrors.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport com.google.common.base.Equivalence;\nimport com.google.common.collect.ImmutableMap;\nimport java.lang.annotation.Annotation;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.Optional;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.Name;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.util.SimpleElementVisitor6;\n\nfinal class Mirrors {\n  private Mirrors() {}\n\n  static Name getQualifiedName(DeclaredType type) {\n    return type.asElement()\n        .accept(\n            new SimpleElementVisitor6<Name, Void>() {\n              @Override\n              protected Name defaultAction(Element e, Void p) {\n                throw new AssertionError(\"DeclaredTypes should be TypeElements\");\n              }\n\n              @Override\n              public Name visitType(TypeElement e, Void p) {\n                return e.getQualifiedName();\n              }\n            },\n            null);\n  }\n\n  /**\n   * Returns an annotation value map with {@link String} keys instead of {@link ExecutableElement}\n   * instances.\n   */\n  static ImmutableMap<String, AnnotationValue> simplifyAnnotationValueMap(\n      Map<? extends ExecutableElement, ? extends AnnotationValue> annotationValueMap) {\n    ImmutableMap.Builder<String, AnnotationValue> builder = ImmutableMap.builder();\n    for (Entry<? extends ExecutableElement, ? extends AnnotationValue> entry :\n        annotationValueMap.entrySet()) {\n      builder.put(entry.getKey().getSimpleName().toString(), entry.getValue());\n    }\n    return builder.build();\n  }\n\n  /**\n   * Get the {@link AnnotationMirror} for the type {@code annotationType} present on the given\n   * {@link Element} if it exists.\n   */\n  static Optional<AnnotationMirror> getAnnotationMirror(\n      Element element, Class<? extends Annotation> annotationType) {\n    String annotationName = annotationType.getName();\n    return element.getAnnotationMirrors().stream()\n        .filter(a -> getQualifiedName(a.getAnnotationType()).contentEquals(annotationName))\n        .<AnnotationMirror>map(x -> x) // get rid of wildcard <? extends AnnotationMirror>\n        .findFirst();\n  }\n\n  /**\n   * Wraps an {@link Optional} of a type in an {@code Optional} of a {@link Equivalence.Wrapper} for\n   * that type.\n   */\n  // TODO(ronshapiro): this is used in AutoFactory and Dagger, consider moving it into auto-common.\n  static <T> Optional<Equivalence.Wrapper<T>> wrapOptionalInEquivalence(\n      Equivalence<T> equivalence, Optional<T> optional) {\n    return optional.map(equivalence::wrap);\n  }\n\n  /**\n   * Unwraps an {@link Optional} of a {@link Equivalence.Wrapper} into an {@code Optional} of the\n   * underlying type.\n   */\n  static <T> Optional<T> unwrapOptionalEquivalence(\n      Optional<Equivalence.Wrapper<T>> wrappedOptional) {\n    return wrappedOptional.map(Equivalence.Wrapper::get);\n  }\n}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/processor/PackageAndClass.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport com.google.auto.value.AutoValue;\n\n/** A Java class name, separated into its package part and its class part. */\n@AutoValue\nabstract class PackageAndClass {\n  /**\n   * The package part of this class name. For {@code java.util.Map.Entry}, it would be {@code\n   * java.util}.\n   */\n  abstract String packageName();\n\n  /**\n   * The class part of this class name. For {@code java.util.Map.Entry}, it would be {@code\n   * Map.Entry}.\n   */\n  abstract String className();\n\n  static PackageAndClass of(String packageName, String className) {\n    return new AutoValue_PackageAndClass(packageName, className);\n  }\n}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/processor/Parameter.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport static com.google.auto.factory.processor.Mirrors.unwrapOptionalEquivalence;\nimport static com.google.auto.factory.processor.Mirrors.wrapOptionalInEquivalence;\nimport static com.google.common.base.Preconditions.checkArgument;\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static com.google.common.collect.ImmutableSet.toImmutableSet;\n\nimport com.google.auto.common.AnnotationMirrors;\nimport com.google.auto.common.MoreElements;\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.value.AutoValue;\nimport com.google.common.base.Equivalence;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Lists;\nimport com.google.common.collect.Sets;\nimport java.util.List;\nimport java.util.Optional;\nimport java.util.Set;\nimport java.util.stream.Stream;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.Types;\n\n/**\n * Model for a parameter from an {@link com.google.auto.factory.AutoFactory} constructor or\n * implementation method.\n */\n@AutoValue\nabstract class Parameter {\n\n  /**\n   * The original type of the parameter, while {@code key().type()} erases the wrapped {@code\n   * Provider}, if any.\n   */\n  abstract Equivalence.Wrapper<TypeMirror> type();\n\n  boolean isPrimitive() {\n    return type().get().getKind().isPrimitive();\n  }\n\n  /** The name of the parameter. */\n  abstract String name();\n\n  abstract Key key();\n\n  /** Annotations on the parameter (not its type). */\n  abstract ImmutableList<Equivalence.Wrapper<AnnotationMirror>> annotationWrappers();\n\n  ImmutableList<AnnotationMirror> annotations() {\n    return annotationWrappers().stream().map(Equivalence.Wrapper::get).collect(toImmutableList());\n  }\n\n  abstract Optional<Equivalence.Wrapper<AnnotationMirror>> nullableWrapper();\n\n  Optional<AnnotationMirror> nullable() {\n    return unwrapOptionalEquivalence(nullableWrapper());\n  }\n\n  private static Parameter forVariableElement(\n      VariableElement variable, TypeMirror type, Types types, InjectApi injectApi) {\n    ImmutableList<AnnotationMirror> allAnnotations =\n        Stream.of(variable.getAnnotationMirrors(), type.getAnnotationMirrors())\n            .flatMap(List::stream)\n            .collect(toImmutableList());\n    Optional<AnnotationMirror> nullable =\n        allAnnotations.stream().filter(Parameter::isNullable).findFirst();\n    Key key = Key.create(type, allAnnotations, types, injectApi);\n\n    ImmutableSet<Equivalence.Wrapper<AnnotationMirror>> typeAnnotationWrappers =\n        type.getAnnotationMirrors().stream()\n            .map(AnnotationMirrors.equivalence()::wrap)\n            .collect(toImmutableSet());\n    ImmutableList<Equivalence.Wrapper<AnnotationMirror>> parameterAnnotationWrappers =\n        variable.getAnnotationMirrors().stream()\n            .map(AnnotationMirrors.equivalence()::wrap)\n            .filter(annotation -> !typeAnnotationWrappers.contains(annotation))\n            .collect(toImmutableList());\n\n    return new AutoValue_Parameter(\n        MoreTypes.equivalence().wrap(type),\n        variable.getSimpleName().toString(),\n        key,\n        parameterAnnotationWrappers,\n        wrapOptionalInEquivalence(AnnotationMirrors.equivalence(), nullable));\n  }\n\n  private static boolean isNullable(AnnotationMirror annotation) {\n    TypeElement annotationType = MoreElements.asType(annotation.getAnnotationType().asElement());\n    return annotationType.getSimpleName().contentEquals(\"Nullable\")\n        || annotationType\n            .getQualifiedName()\n            .toString()\n            // For NullableDecl and NullableType compatibility annotations\n            .startsWith(\"org.checkerframework.checker.nullness.compatqual.Nullable\");\n  }\n\n  static ImmutableSet<Parameter> forParameterList(\n      List<? extends VariableElement> variables,\n      List<? extends TypeMirror> variableTypes,\n      Types types,\n      InjectApi injectApi) {\n    checkArgument(variables.size() == variableTypes.size());\n    ImmutableSet.Builder<Parameter> builder = ImmutableSet.builder();\n    Set<String> names = Sets.newHashSetWithExpectedSize(variables.size());\n    for (int i = 0; i < variables.size(); i++) {\n      Parameter parameter =\n          forVariableElement(variables.get(i), variableTypes.get(i), types, injectApi);\n      checkArgument(names.add(parameter.name()), \"Duplicate parameter name: %s\", parameter.name());\n      builder.add(parameter);\n    }\n    ImmutableSet<Parameter> parameters = builder.build();\n    checkArgument(variables.size() == parameters.size());\n    return parameters;\n  }\n\n  static ImmutableSet<Parameter> forParameterList(\n      List<? extends VariableElement> variables, Types types, InjectApi injectApi) {\n    List<TypeMirror> variableTypes = Lists.newArrayListWithExpectedSize(variables.size());\n    for (VariableElement var : variables) {\n      variableTypes.add(var.asType());\n    }\n    return forParameterList(variables, variableTypes, types, injectApi);\n  }\n}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/processor/ProvidedChecker.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport static com.google.auto.common.MoreElements.isAnnotationPresent;\nimport static com.google.common.base.Preconditions.checkArgument;\nimport static javax.tools.Diagnostic.Kind.ERROR;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.Provided;\nimport javax.annotation.processing.Messager;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.util.ElementKindVisitor6;\nimport org.jspecify.annotations.Nullable;\n\nfinal class ProvidedChecker {\n  private final Messager messager;\n\n  ProvidedChecker(Messager messager) {\n    this.messager = messager;\n  }\n\n  void checkProvidedParameter(Element element) {\n    checkArgument(\n        isAnnotationPresent(element, Provided.class), \"%s not annoated with @Provided\", element);\n    element.accept(\n        new ElementKindVisitor6<@Nullable Void, @Nullable Void>() {\n          @Override\n          protected @Nullable Void defaultAction(Element e, @Nullable Void p) {\n            throw new AssertionError(\"Provided can only be applied to parameters\");\n          }\n\n          @Override\n          public @Nullable Void visitVariableAsParameter(\n              VariableElement providedParameter, @Nullable Void p) {\n            providedParameter\n                .getEnclosingElement()\n                .accept(\n                    new ElementKindVisitor6<@Nullable Void, @Nullable Void>() {\n                      @Override\n                      protected @Nullable Void defaultAction(Element e, @Nullable Void p) {\n                        raiseError(\n                            providedParameter, \"@%s may only be applied to constructor parameters\");\n                        return null;\n                      }\n\n                      @Override\n                      public @Nullable Void visitExecutableAsConstructor(\n                          ExecutableElement constructor, @Nullable Void p) {\n                        if (!(annotatedWithAutoFactory(constructor)\n                            || annotatedWithAutoFactory(constructor.getEnclosingElement()))) {\n                          raiseError(\n                              providedParameter,\n                              \"@%s may only be applied to constructors requesting an auto-factory\");\n                        }\n                        return null;\n                      }\n                    },\n                    p);\n            return null;\n          }\n        },\n        null);\n  }\n\n  private void raiseError(VariableElement providedParameter, String messageFormat) {\n    messager.printMessage(\n        ERROR,\n        String.format(messageFormat, Provided.class.getSimpleName()),\n        providedParameter,\n        Mirrors.getAnnotationMirror(providedParameter, Provided.class).get());\n  }\n\n  private static boolean annotatedWithAutoFactory(Element e) {\n    return isAnnotationPresent(e, AutoFactory.class);\n  }\n}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/processor/ProviderField.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport static com.google.auto.factory.processor.Mirrors.unwrapOptionalEquivalence;\nimport static com.google.auto.factory.processor.Mirrors.wrapOptionalInEquivalence;\n\nimport com.google.auto.common.AnnotationMirrors;\nimport com.google.auto.value.AutoValue;\nimport com.google.common.base.Equivalence;\nimport java.util.Optional;\nimport javax.lang.model.element.AnnotationMirror;\n\n@AutoValue\nabstract class ProviderField {\n  abstract String name();\n\n  abstract Key key();\n\n  abstract Optional<Equivalence.Wrapper<AnnotationMirror>> nullableWrapper();\n\n  Optional<AnnotationMirror> nullable() {\n    return unwrapOptionalEquivalence(nullableWrapper());\n  }\n\n  static ProviderField create(String name, Key key, Optional<AnnotationMirror> nullable) {\n    return new AutoValue_ProviderField(\n        name, key, wrapOptionalInEquivalence(AnnotationMirrors.equivalence(), nullable));\n  }\n}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/processor/TypeVariables.java",
    "content": "/*\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport static com.google.common.base.Preconditions.checkNotNull;\n\nimport com.google.common.collect.ImmutableSet;\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.type.ArrayType;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.IntersectionType;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.type.TypeVariable;\nimport javax.lang.model.type.UnionType;\nimport javax.lang.model.type.WildcardType;\nimport javax.lang.model.util.SimpleTypeVisitor8;\n\nfinal class TypeVariables {\n  private TypeVariables() {}\n\n  static ImmutableSet<TypeVariable> getReferencedTypeVariables(TypeMirror type) {\n    checkNotNull(type);\n    return type.accept(ReferencedTypeVariables.INSTANCE, new HashSet<>());\n  }\n\n  private static final class ReferencedTypeVariables\n      extends SimpleTypeVisitor8<ImmutableSet<TypeVariable>, Set<Element>> {\n\n    private static final ReferencedTypeVariables INSTANCE = new ReferencedTypeVariables();\n\n    ReferencedTypeVariables() {\n      super(ImmutableSet.of());\n    }\n\n    @Override\n    public ImmutableSet<TypeVariable> visitArray(ArrayType t, Set<Element> visited) {\n      return t.getComponentType().accept(this, visited);\n    }\n\n    @Override\n    public ImmutableSet<TypeVariable> visitDeclared(DeclaredType t, Set<Element> visited) {\n      if (!visited.add(t.asElement())) {\n        return ImmutableSet.of();\n      }\n      ImmutableSet.Builder<TypeVariable> typeVariables = ImmutableSet.builder();\n      for (TypeMirror typeArgument : t.getTypeArguments()) {\n        typeVariables.addAll(typeArgument.accept(this, visited));\n      }\n      return typeVariables.build();\n    }\n\n    @Override\n    public ImmutableSet<TypeVariable> visitTypeVariable(TypeVariable t, Set<Element> visited) {\n      if (!visited.add(t.asElement())) {\n        return ImmutableSet.of();\n      }\n      ImmutableSet.Builder<TypeVariable> typeVariables = ImmutableSet.builder();\n      typeVariables.add(t);\n      typeVariables.addAll(t.getLowerBound().accept(this, visited));\n      typeVariables.addAll(t.getUpperBound().accept(this, visited));\n      return typeVariables.build();\n    }\n\n    @Override\n    public ImmutableSet<TypeVariable> visitUnion(UnionType t, Set<Element> visited) {\n      ImmutableSet.Builder<TypeVariable> typeVariables = ImmutableSet.builder();\n      for (TypeMirror unionType : t.getAlternatives()) {\n        typeVariables.addAll(unionType.accept(this, visited));\n      }\n      return typeVariables.build();\n    }\n\n    @Override\n    public ImmutableSet<TypeVariable> visitIntersection(IntersectionType t, Set<Element> visited) {\n      ImmutableSet.Builder<TypeVariable> typeVariables = ImmutableSet.builder();\n      for (TypeMirror intersectionType : t.getBounds()) {\n        typeVariables.addAll(intersectionType.accept(this, visited));\n      }\n      return typeVariables.build();\n    }\n\n    @Override\n    public ImmutableSet<TypeVariable> visitWildcard(WildcardType t, Set<Element> visited) {\n      ImmutableSet.Builder<TypeVariable> typeVariables = ImmutableSet.builder();\n      TypeMirror extendsBound = t.getExtendsBound();\n      if (extendsBound != null) {\n        typeVariables.addAll(extendsBound.accept(this, visited));\n      }\n      TypeMirror superBound = t.getSuperBound();\n      if (superBound != null) {\n        typeVariables.addAll(superBound.accept(this, visited));\n      }\n      return typeVariables.build();\n    }\n  }\n}\n"
  },
  {
    "path": "factory/src/main/java/com/google/auto/factory/processor/package-info.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n/**\n * This package contains the annotation processor that implements the {@link\n * com.google.auto.factory.AutoFactory} API.\n */\n@NullMarked\npackage com.google.auto.factory.processor;\n\nimport org.jspecify.annotations.NullMarked;\n"
  },
  {
    "path": "factory/src/test/java/com/google/auto/factory/processor/AutoFactoryDeclarationTest.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport static com.google.auto.factory.processor.AutoFactoryDeclaration.Factory.isValidIdentifier;\nimport static com.google.common.truth.Truth.assertThat;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic class AutoFactoryDeclarationTest {\n  @Test\n  public void identifiers() {\n    assertThat(isValidIdentifier(\"String\")).isTrue();\n    assertThat(isValidIdentifier(\"9CantStartWithNumber\")).isFalse();\n    assertThat(isValidIdentifier(\"enum\")).isFalse();\n    assertThat(isValidIdentifier(\"goto\")).isFalse();\n    assertThat(isValidIdentifier(\"InvalidCharacter!\")).isFalse();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/java/com/google/auto/factory/processor/AutoFactoryProcessorNegativeTest.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.testing.compile.CompilationSubject.assertThat;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.testing.compile.Compilation;\nimport com.google.testing.compile.Compiler;\nimport com.google.testing.compile.JavaFileObjects;\nimport java.io.File;\nimport java.net.URL;\nimport javax.tools.JavaFileObject;\nimport javax.tools.StandardLocation;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/** Testing compilation errors from {@link AutoFactoryProcessor}. */\n@RunWith(JUnit4.class)\npublic class AutoFactoryProcessorNegativeTest {\n  private final Compiler javac = Compiler.javac().withProcessors(new AutoFactoryProcessor());\n\n  @Test\n  public void failsWithMixedFinals() {\n    JavaFileObject file = JavaFileObjects.forResource(\"bad/MixedFinals.java\");\n    Compilation compilation = javac.compile(file);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Cannot mix allowSubclasses=true and allowSubclasses=false in one factory.\")\n        .inFile(file)\n        .onLine(24);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Cannot mix allowSubclasses=true and allowSubclasses=false in one factory.\")\n        .inFile(file)\n        .onLine(27);\n  }\n\n  @Test\n  public void providedButNoAutoFactory() {\n    JavaFileObject file = JavaFileObjects.forResource(\"bad/ProvidedButNoAutoFactory.java\");\n    Compilation compilation = javac.compile(file);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"@Provided may only be applied to constructors requesting an auto-factory\")\n        .inFile(file)\n        .onLineContaining(\"@Provided\");\n  }\n\n  @Test\n  public void providedOnMethodParameter() {\n    JavaFileObject file = JavaFileObjects.forResource(\"bad/ProvidedOnMethodParameter.java\");\n    Compilation compilation = javac.compile(file);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\"@Provided may only be applied to constructor parameters\")\n        .inFile(file)\n        .onLineContaining(\"@Provided\");\n  }\n\n  @Test\n  public void invalidCustomName() {\n    JavaFileObject file = JavaFileObjects.forResource(\"bad/InvalidCustomName.java\");\n    Compilation compilation = javac.compile(file);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\"\\\"SillyFactory!\\\" is not a valid Java identifier\")\n        .inFile(file)\n        .onLineContaining(\"SillyFactory!\");\n  }\n\n  @Test\n  public void factoryExtendingAbstractClass_withConstructorParams() {\n    JavaFileObject file =\n        JavaFileObjects.forResource(\"bad/FactoryExtendingAbstractClassWithConstructorParams.java\");\n    Compilation compilation = javac.compile(file);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"tests.FactoryExtendingAbstractClassWithConstructorParams.AbstractFactory is not a\"\n                + \" valid supertype for a factory. Factory supertypes must have a no-arg\"\n                + \" constructor.\")\n        .inFile(file)\n        .onLineContaining(\"@AutoFactory\");\n  }\n\n  @Test\n  public void factoryExtendingInterface() {\n    JavaFileObject file = JavaFileObjects.forResource(\"bad/InterfaceSupertype.java\");\n    Compilation compilation = javac.compile(file);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"java.lang.Runnable is not a valid supertype for a factory. Supertypes must be\"\n                + \" non-final classes.\")\n        .inFile(file)\n        .onLineContaining(\"@AutoFactory\");\n  }\n\n  @Test\n  public void factoryExtendingEnum() {\n    JavaFileObject file = JavaFileObjects.forResource(\"bad/EnumSupertype.java\");\n    Compilation compilation = javac.compile(file);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"java.util.concurrent.TimeUnit is not a valid supertype for a factory. Supertypes must\"\n                + \" be non-final classes.\")\n        .inFile(file)\n        .onLineContaining(\"@AutoFactory\");\n  }\n\n  @Test\n  public void factoryExtendingFinalClass() {\n    JavaFileObject file = JavaFileObjects.forResource(\"bad/FinalSupertype.java\");\n    Compilation compilation = javac.compile(file);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"java.lang.Boolean is not a valid supertype for a factory. Supertypes must be\"\n                + \" non-final classes.\")\n        .inFile(file)\n        .onLineContaining(\"@AutoFactory\");\n  }\n\n  /**\n   * We don't currently allow you to have more than one {@code @AnnotationsToApply} annotation for\n   * any given AutoFactory class.\n   */\n  @Test\n  public void annotationsToApplyMultiple() {\n    JavaFileObject file = JavaFileObjects.forResource(\"bad/AnnotationsToApplyMultiple.java\");\n    Compilation compilation = javac.compile(file);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\"Multiple @AnnotationsToApply annotations are not supported\");\n  }\n\n  /**\n   * We also don't allow you to have the same annotation appear more than once inside a given\n   * {@code @AnnotationsToApply}, even with the same values.\n   */\n  @Test\n  public void annotationsToApplyRepeated() {\n    JavaFileObject file = JavaFileObjects.forResource(\"bad/AnnotationsToApplyRepeated.java\");\n    Compilation compilation = javac.compile(file);\n    assertThat(compilation).failed();\n    assertThat(compilation).hadErrorContaining(\"More than one @java.lang.SuppressWarnings\");\n  }\n\n  @Test\n  public void annotationsToApplyNotAnnotations() {\n    JavaFileObject file = JavaFileObjects.forResource(\"bad/AnnotationsToApplyNotAnnotations.java\");\n    Compilation compilation = javac.compile(file);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Members of an @AnnotationsToApply annotation must themselves be annotations;\"\n                + \" whatIsThis has type int\")\n        .inFile(file)\n        .onLineContaining(\"whatIsThis\");\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Members of an @AnnotationsToApply annotation must themselves be annotations;\"\n                + \" andWhatIsThis has type com.google.errorprone.annotations.Immutable[]\")\n        .inFile(file)\n        .onLineContaining(\"andWhatIsThis\");\n  }\n\n  @Test\n  public void noInjectApi() throws Exception {\n    URL autoFactoryUrl =\n        Class.forName(\"com.google.auto.factory.AutoFactory\")\n            .getProtectionDomain()\n            .getCodeSource()\n            .getLocation();\n    assertThat(autoFactoryUrl.getProtocol()).isEqualTo(\"file\");\n    File autoFactoryFile = new File(autoFactoryUrl.getPath());\n    Compiler compiler =\n        Compiler.javac()\n            .withProcessors(new AutoFactoryProcessor())\n            .withClasspath(ImmutableList.of(autoFactoryFile));\n    JavaFileObject file = JavaFileObjects.forResource(\"good/SimpleClass.java\");\n    Compilation compilation = compiler.compile(file);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Class path for AutoFactory class must include\"\n                + \" jakarta.inject.{Inject,Provider,Qualifier} or\"\n                + \" javax.inject.{Inject,Provider,Qualifier}\");\n    assertThat(compilation).hadErrorCount(1);\n  }\n\n  /**\n   * AutoFactoryProcessor shouldn't complain about the absence of {@code javax.inject} if there are\n   * no {@code @AutoFactory} classes being compiled. Its {@code init} will be called and will see\n   * the problem, but will say nothing.\n   */\n  @Test\n  public void noInjectApiButNoAutoFactoryEither() {\n    Compiler compiler =\n        Compiler.javac()\n            .withProcessors(new AutoFactoryProcessor())\n            .withClasspath(ImmutableList.of());\n    JavaFileObject file =\n        JavaFileObjects.forSourceString(\"test.Foo\", \"package test; public class Foo {}\");\n    Compilation compilation = compiler.compile(file);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation).generatedFile(StandardLocation.CLASS_OUTPUT, \"test\", \"Foo.class\");\n  }\n}\n"
  },
  {
    "path": "factory/src/test/java/com/google/auto/factory/processor/AutoFactoryProcessorTest.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.factory.processor;\n\nimport static com.google.common.base.Preconditions.checkArgument;\nimport static com.google.common.base.Preconditions.checkState;\nimport static com.google.common.base.StandardSystemProperty.JAVA_SPECIFICATION_VERSION;\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.common.truth.TruthJUnit.assume;\nimport static com.google.testing.compile.CompilationSubject.assertThat;\nimport static java.lang.Math.max;\nimport static java.lang.Math.min;\nimport static java.nio.charset.StandardCharsets.UTF_8;\nimport static java.util.regex.Pattern.MULTILINE;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.io.Resources;\nimport com.google.testing.compile.Compilation;\nimport com.google.testing.compile.Compiler;\nimport com.google.testing.compile.JavaFileObjects;\nimport com.google.testing.junit.testparameterinjector.TestParameter;\nimport com.google.testing.junit.testparameterinjector.TestParameterInjector;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.UncheckedIOException;\nimport java.net.URL;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport javax.lang.model.SourceVersion;\nimport javax.tools.JavaFileObject;\nimport org.junit.AfterClass;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\n/** Functional tests for the {@link AutoFactoryProcessor}. */\n@RunWith(TestParameterInjector.class)\npublic class AutoFactoryProcessorTest {\n  private final Config config;\n\n  public AutoFactoryProcessorTest(@TestParameter Config config) {\n    this.config = config;\n  }\n\n  private enum InjectPackage {\n    JAVAX,\n    JAKARTA\n  }\n\n  /**\n   * Each test configuration specifies whether javax or jakarta or both are on the classpath, which\n   * one is expected to be chosen, and any {@code -A} options.\n   */\n  private enum Config {\n    JAVAX_ONLY_ON_CLASSPATH(ImmutableList.of(InjectPackage.JAVAX), InjectPackage.JAVAX),\n    JAKARTA_ONLY_ON_CLASSPATH(ImmutableList.of(InjectPackage.JAKARTA), InjectPackage.JAKARTA),\n    BOTH_ON_CLASSPATH(\n        ImmutableList.of(InjectPackage.JAVAX, InjectPackage.JAKARTA),\n        InjectPackage.JAKARTA),\n    EXPLICIT_JAVAX(\n        ImmutableList.of(InjectPackage.JAVAX, InjectPackage.JAKARTA),\n        InjectPackage.JAVAX,\n        ImmutableList.of(\"-A\" + AutoFactoryProcessor.INJECT_API_OPTION + \"=javax\")),\n    EXPLICIT_JAKARTA(\n        ImmutableList.of(InjectPackage.JAVAX, InjectPackage.JAKARTA),\n        InjectPackage.JAKARTA,\n        ImmutableList.of(\"-A\" + AutoFactoryProcessor.INJECT_API_OPTION + \"=jakarta\"));\n\n    /**\n     * Config that is used for negative tests, and to update the golden files. Since those files use\n     * {@code javax.inject}, we need a config that specifies that package.\n     */\n    static final Config DEFAULT = EXPLICIT_JAVAX;\n\n    final ImmutableList<InjectPackage> packagesOnClasspath;\n    final InjectPackage expectedPackage;\n    final ImmutableList<String> options;\n\n    Config(ImmutableList<InjectPackage> packagesOnClasspath, InjectPackage expectedPackage) {\n      this(packagesOnClasspath, expectedPackage, ImmutableList.of());\n    }\n\n    Config(\n        ImmutableList<InjectPackage> packagesOnClasspath,\n        InjectPackage expectedPackage,\n        ImmutableList<String> options) {\n      this.packagesOnClasspath = packagesOnClasspath;\n      this.expectedPackage = expectedPackage;\n      this.options = options;\n    }\n\n    static final ImmutableList<File> COMMON_CLASSPATH =\n        ImmutableList.of(\n            fileForClass(\"com.google.auto.factory.AutoFactory\"),\n            fileForClass(\"com.google.errorprone.annotations.Immutable\"),\n            fileForClass(\"javax.annotation.Nullable\"),\n            fileForClass(\"org.checkerframework.checker.nullness.compatqual.NullableType\"));\n    static final File JAVAX_CLASSPATH = fileForClass(\"javax.inject.Provider\");\n    static final File JAKARTA_CLASSPATH = fileForClass(\"jakarta.inject.Provider\");\n\n    static File fileForClass(String className) {\n      Class<?> c;\n      try {\n        c = Class.forName(className);\n      } catch (ClassNotFoundException e) {\n        throw new IllegalArgumentException(e);\n      }\n      URL url = c.getProtectionDomain().getCodeSource().getLocation();\n      assertThat(url.getProtocol()).isEqualTo(\"file\");\n      return new File(url.getPath());\n    }\n\n    ImmutableList<File> classpath() {\n      ImmutableList.Builder<File> classpathBuilder =\n          ImmutableList.<File>builder().addAll(COMMON_CLASSPATH);\n      if (packagesOnClasspath.contains(InjectPackage.JAVAX)) {\n        classpathBuilder.add(JAVAX_CLASSPATH);\n      }\n      if (packagesOnClasspath.contains(InjectPackage.JAKARTA)) {\n        classpathBuilder.add(JAKARTA_CLASSPATH);\n      }\n      return classpathBuilder.build();\n    }\n\n    Compiler javac() {\n      return Compiler.javac()\n          .withClasspath(classpath())\n          .withProcessors(new AutoFactoryProcessor())\n          .withOptions(options);\n    }\n  }\n\n  private static volatile boolean goldenFileFailures;\n\n  private static final String GOLDEN_FILE_ROOT_ENV = \"GOLDEN_FILE_ROOT\";\n  private static final String GOLDEN_FILE_ROOT = System.getenv(GOLDEN_FILE_ROOT_ENV);\n  private static final Pattern CLASS_START =\n      Pattern.compile(\"^(public )?(final )?class \", MULTILINE);\n\n  @AfterClass\n  public static void explainGoldenFileFailures() {\n    if (goldenFileFailures) {\n      System.err.println();\n      System.err.println(\"Some golden-file tests failed.\");\n    }\n  }\n\n  /**\n   * Runs a golden-file test, and optionally updates the golden file if the test fails.\n   *\n   * <p>If the golden file does not match current generated output, and the environment variable\n   * {@value #GOLDEN_FILE_ROOT_ENV} is set to the root directory for resources, then the golden file\n   * will be rewritten to match the generated output.\n   *\n   * @param inputResources resource names for the sources that the test will compile\n   * @param expectedOutput map where each key is the name of an expected generated file, and each\n   *     corresponding value is the name of the resource with the text that should have been\n   *     generated\n   */\n  private void goldenTest(\n      ImmutableList<String> inputResources, ImmutableMap<String, String> expectedOutput) {\n    ImmutableList<JavaFileObject> javaFileObjects =\n        inputResources.stream().map(this::goldenFile).collect(toImmutableList());\n    Compilation compilation = config.javac().compile(javaFileObjects);\n    assertThat(compilation).succeededWithoutWarnings();\n    expectedOutput.forEach(\n        (className, expectedSourceResource) -> {\n          try {\n            assertThat(compilation)\n                .generatedSourceFile(className)\n                .hasSourceEquivalentTo(loadExpectedFile(expectedSourceResource));\n          } catch (AssertionError e) {\n            if (GOLDEN_FILE_ROOT == null) {\n              goldenFileFailures = true;\n              throw e;\n            }\n            if (config.equals(Config.DEFAULT)) {\n              try {\n                updateGoldenFile(compilation, className, expectedSourceResource);\n              } catch (IOException e2) {\n                throw new UncheckedIOException(e2);\n              }\n            }\n          }\n        });\n  }\n\n  private JavaFileObject goldenFile(String resourceName) {\n    try {\n      URL resourceUrl = Resources.getResource(resourceName);\n      String source = Resources.toString(resourceUrl, UTF_8);\n      if (config.expectedPackage.equals(InjectPackage.JAKARTA)) {\n        source = source.replace(\"javax.inject\", \"jakarta.inject\");\n      }\n      String className = resourceName.replaceFirst(\"\\\\.java$\", \"\").replace('/', '.');\n      return JavaFileObjects.forSourceString(className, source);\n    } catch (IOException e) {\n      throw new UncheckedIOException(e);\n    }\n  }\n\n  private void updateGoldenFile(Compilation compilation, String className, String relativePath)\n      throws IOException {\n    Path goldenFileRootPath = Paths.get(GOLDEN_FILE_ROOT);\n    Path goldenFilePath = goldenFileRootPath.resolve(relativePath);\n    checkState(\n        Files.isRegularFile(goldenFilePath) && Files.isWritable(goldenFilePath),\n        \"%s does not exist or can't be written\",\n        goldenFilePath);\n\n    JavaFileObject newJavaFileObject =\n        compilation\n            .generatedSourceFile(className)\n            .orElseThrow(() -> new IllegalStateException(\"No generated file for \" + className));\n    // We can't use Files.readString here because this test must run on Java 8.\n    String oldContent = new String(Files.readAllBytes(goldenFilePath), UTF_8);\n    String newContent =\n        newJavaFileObject.getCharContent(/* ignoreEncodingErrors= */ false).toString();\n\n    // We want to preserve the copyright notice and some minor Google-internal things that are\n    // stripped from the open-source version. So keep text from the old golden file before the\n    // class declaration.\n    int oldPosition = indexOfClassStartIn(oldContent, \"original \" + relativePath);\n    int newPosition = indexOfClassStartIn(newContent, \"generated \" + relativePath);\n    String updatedContent =\n        oldContent.substring(0, oldPosition) + newContent.substring(newPosition);\n    // We can't use Files.writeString here because this test must run on Java 8.\n    Files.write(goldenFilePath, updatedContent.getBytes(UTF_8));\n    System.err.println(\"Updated \" + goldenFilePath);\n  }\n\n  private int indexOfClassStartIn(String content, String where) {\n    Matcher matcher = CLASS_START.matcher(content);\n    boolean found = matcher.find();\n    checkArgument(found, \"Pattern /%s/ not found in %s:\\n%s\", CLASS_START, where, content);\n    return matcher.start();\n  }\n\n  @Test\n  public void simpleClass() {\n    goldenTest(\n        ImmutableList.of(\"good/SimpleClass.java\"),\n        ImmutableMap.of(\"tests.SimpleClassFactory\", \"expected/SimpleClassFactory.java\"));\n  }\n\n  @Test\n  public void simpleClassWithConstructorThrowsClause() {\n    goldenTest(\n        ImmutableList.of(\"good/SimpleClassThrows.java\"),\n        ImmutableMap.of(\n            \"tests.SimpleClassThrowsFactory\", \"expected/SimpleClassThrowsFactory.java\"));\n  }\n\n  @Test\n  public void nestedClasses() {\n    goldenTest(\n        ImmutableList.of(\"good/NestedClasses.java\"),\n        ImmutableMap.of(\n            \"tests.NestedClasses_SimpleNestedClassFactory\",\n            \"expected/NestedClasses_SimpleNestedClassFactory.java\",\n            \"tests.NestedClassCustomNamedFactory\",\n            \"expected/NestedClassCustomNamedFactory.java\"));\n  }\n\n  @Test\n  public void simpleClassNonFinal() {\n    goldenTest(\n        ImmutableList.of(\"good/SimpleClassNonFinal.java\"),\n        ImmutableMap.of(\n            \"tests.SimpleClassNonFinalFactory\", \"expected/SimpleClassNonFinalFactory.java\"));\n  }\n\n  @Test\n  public void publicClass() {\n    goldenTest(\n        ImmutableList.of(\"good/PublicClass.java\"),\n        ImmutableMap.of(\"tests.PublicClassFactory\", \"expected/PublicClassFactory.java\"));\n  }\n\n  @Test\n  public void simpleClassCustomName() {\n    goldenTest(\n        ImmutableList.of(\"good/SimpleClassCustomName.java\"),\n        ImmutableMap.of(\"tests.CustomNamedFactory\", \"expected/CustomNamedFactory.java\"));\n  }\n\n  @Test\n  public void simpleClassMixedDeps() {\n    goldenTest(\n        ImmutableList.of(\"good/SimpleClassMixedDeps.java\", \"support/AQualifier.java\"),\n        ImmutableMap.of(\n            \"tests.SimpleClassMixedDepsFactory\", \"expected/SimpleClassMixedDepsFactory.java\"));\n  }\n\n  @Test\n  public void simpleClassPassedDeps() {\n    goldenTest(\n        ImmutableList.of(\"good/SimpleClassPassedDeps.java\"),\n        ImmutableMap.of(\n            \"tests.SimpleClassPassedDepsFactory\", \"expected/SimpleClassPassedDepsFactory.java\"));\n  }\n\n  @Test\n  public void simpleClassProvidedDeps() {\n    goldenTest(\n        ImmutableList.of(\n            \"good/SimpleClassProvidedDeps.java\",\n            \"support/AQualifier.java\",\n            \"support/BQualifier.java\"),\n        ImmutableMap.of(\n            \"tests.SimpleClassProvidedDepsFactory\",\n            \"expected/SimpleClassProvidedDepsFactory.java\"));\n  }\n\n  @Test\n  public void simpleClassProvidedProviderDeps() {\n    goldenTest(\n        ImmutableList.of(\n            \"good/SimpleClassProvidedProviderDeps.java\",\n            \"support/AQualifier.java\",\n            \"support/BQualifier.java\"),\n        ImmutableMap.of(\n            \"tests.SimpleClassProvidedProviderDepsFactory\",\n            \"expected/SimpleClassProvidedProviderDepsFactory.java\"));\n  }\n\n  @Test\n  public void constructorAnnotated() {\n    goldenTest(\n        ImmutableList.of(\"good/ConstructorAnnotated.java\"),\n        ImmutableMap.of(\n            \"tests.ConstructorAnnotatedFactory\", \"expected/ConstructorAnnotatedFactory.java\"));\n  }\n\n  @Test\n  public void constructorWithThrowsClauseAnnotated() {\n    goldenTest(\n        ImmutableList.of(\"good/ConstructorAnnotatedThrows.java\"),\n        ImmutableMap.of(\n            \"tests.ConstructorAnnotatedThrowsFactory\",\n            \"expected/ConstructorAnnotatedThrowsFactory.java\"));\n  }\n\n  @Test\n  public void constructorAnnotatedNonFinal() {\n    goldenTest(\n        ImmutableList.of(\"good/ConstructorAnnotatedNonFinal.java\"),\n        ImmutableMap.of(\n            \"tests.ConstructorAnnotatedNonFinalFactory\",\n            \"expected/ConstructorAnnotatedNonFinalFactory.java\"));\n  }\n\n  @Test\n  public void simpleClassImplementingMarker() {\n    goldenTest(\n        ImmutableList.of(\"good/SimpleClassImplementingMarker.java\"),\n        ImmutableMap.of(\n            \"tests.SimpleClassImplementingMarkerFactory\",\n            \"expected/SimpleClassImplementingMarkerFactory.java\"));\n  }\n\n  @Test\n  public void simpleClassImplementingSimpleInterface() {\n    goldenTest(\n        ImmutableList.of(\"good/SimpleClassImplementingSimpleInterface.java\"),\n        ImmutableMap.of(\n            \"tests.SimpleClassImplementingSimpleInterfaceFactory\",\n            \"expected/SimpleClassImplementingSimpleInterfaceFactory.java\"));\n  }\n\n  @Test\n  public void mixedDepsImplementingInterfaces() {\n    goldenTest(\n        ImmutableList.of(\"good/MixedDepsImplementingInterfaces.java\"),\n        ImmutableMap.of(\n            \"tests.MixedDepsImplementingInterfacesFactory\",\n            \"expected/MixedDepsImplementingInterfacesFactory.java\"));\n  }\n\n  @Test\n  public void factoryExtendingAbstractClass() {\n    goldenTest(\n        ImmutableList.of(\"good/FactoryExtendingAbstractClass.java\"),\n        ImmutableMap.of(\n            \"tests.FactoryExtendingAbstractClassFactory\",\n            \"expected/FactoryExtendingAbstractClassFactory.java\"));\n  }\n\n  @Test\n  public void factoryWithConstructorThrowsClauseExtendingAbstractClass() {\n    goldenTest(\n        ImmutableList.of(\"good/FactoryExtendingAbstractClassThrows.java\"),\n        ImmutableMap.of(\n            \"tests.FactoryExtendingAbstractClassThrowsFactory\",\n            \"expected/FactoryExtendingAbstractClassThrowsFactory.java\"));\n  }\n\n  @Test\n  public void factoryExtendingAbstractClass_multipleConstructors() {\n    goldenTest(\n        ImmutableList.of(\"good/FactoryExtendingAbstractClassWithMultipleConstructors.java\"),\n        ImmutableMap.of());\n  }\n\n  @Test\n  public void factoryImplementingGenericInterfaceExtension() {\n    goldenTest(\n        ImmutableList.of(\"good/FactoryImplementingGenericInterfaceExtension.java\"),\n        ImmutableMap.of(\n            \"tests.FactoryImplementingGenericInterfaceExtensionFactory\",\n            \"expected/FactoryImplementingGenericInterfaceExtensionFactory.java\"));\n  }\n\n  @Test\n  public void multipleFactoriesImpementingInterface() {\n    goldenTest(\n        ImmutableList.of(\"good/MultipleFactoriesImplementingInterface.java\"),\n        ImmutableMap.of(\n            \"tests.MultipleFactoriesImplementingInterface_ClassAFactory\",\n                \"expected/MultipleFactoriesImplementingInterface_ClassAFactory.java\",\n            \"tests.MultipleFactoriesImplementingInterface_ClassBFactory\",\n                \"expected/MultipleFactoriesImplementingInterface_ClassBFactory.java\"));\n  }\n\n  @Test\n  public void classUsingQualifierWithArgs() {\n    goldenTest(\n        ImmutableList.of(\"good/ClassUsingQualifierWithArgs.java\", \"support/QualifierWithArgs.java\"),\n        ImmutableMap.of(\n            \"tests.ClassUsingQualifierWithArgsFactory\",\n            \"expected/ClassUsingQualifierWithArgsFactory.java\"));\n  }\n\n  @Test\n  public void factoryImplementingInterfaceWhichRedeclaresCreateMethods() {\n    goldenTest(\n        ImmutableList.of(\"good/FactoryImplementingCreateMethod.java\"),\n        ImmutableMap.of(\n            \"tests.FactoryImplementingCreateMethod_ConcreteClassFactory\",\n            \"expected/FactoryImplementingCreateMethod_ConcreteClassFactory.java\"));\n  }\n\n  @Test\n  public void nullableParams() {\n    goldenTest(\n        ImmutableList.of(\n            \"good/SimpleClassNullableParameters.java\",\n            \"support/AQualifier.java\",\n            \"support/BQualifier.java\"),\n        ImmutableMap.of(\n            \"tests.SimpleClassNullableParametersFactory\",\n            \"expected/SimpleClassNullableParametersFactory.java\"));\n  }\n\n  @Test\n  public void customNullableType() {\n    goldenTest(\n        ImmutableList.of(\"good/CustomNullable.java\"),\n        ImmutableMap.of(\"tests.CustomNullableFactory\", \"expected/CustomNullableFactory.java\"));\n  }\n\n  @Test\n  public void checkerFrameworkNullableType() {\n    // TYPE_USE annotations are pretty much unusable with annotation processors on Java 8 because\n    // of bugs that mean they only appear in the javax.lang.model API when the compiler feels like\n    // it. Checking for a java.specification.version that does not start with \"1.\" eliminates 8 and\n    // any earlier version.\n    assume().that(JAVA_SPECIFICATION_VERSION.value()).doesNotMatch(\"1\\\\..*\");\n    goldenTest(\n        ImmutableList.of(\"good/CheckerFrameworkNullable.java\"),\n        ImmutableMap.of(\n            \"tests.CheckerFrameworkNullableFactory\",\n            \"expected/CheckerFrameworkNullableFactory.java\"));\n  }\n\n  @Test\n  public void multipleProvidedParamsWithSameKey() {\n    goldenTest(\n        ImmutableList.of(\"good/MultipleProvidedParamsSameKey.java\"),\n        ImmutableMap.of(\n            \"tests.MultipleProvidedParamsSameKeyFactory\",\n            \"expected/MultipleProvidedParamsSameKeyFactory.java\"));\n  }\n\n  @Test\n  public void providerArgumentToCreateMethod() {\n    goldenTest(\n        ImmutableList.of(\"good/ProviderArgumentToCreateMethod.java\"),\n        ImmutableMap.of(\n            \"tests.ProviderArgumentToCreateMethodFactory\",\n            \"expected/ProviderArgumentToCreateMethodFactory.java\"));\n  }\n\n  @Test\n  public void multipleFactoriesConflictingParameterNames() {\n    goldenTest(\n        ImmutableList.of(\n            \"good/MultipleFactoriesConflictingParameterNames.java\", \"support/AQualifier.java\"),\n        ImmutableMap.of(\n            \"tests.MultipleFactoriesConflictingParameterNamesFactory\",\n            \"expected/MultipleFactoriesConflictingParameterNamesFactory.java\"));\n  }\n\n  @Test\n  public void factoryVarargs() {\n    goldenTest(\n        ImmutableList.of(\"good/SimpleClassVarargs.java\"),\n        ImmutableMap.of(\n            \"tests.SimpleClassVarargsFactory\", \"expected/SimpleClassVarargsFactory.java\"));\n  }\n\n  @Test\n  public void onlyPrimitives() {\n    goldenTest(\n        ImmutableList.of(\"good/OnlyPrimitives.java\"),\n        ImmutableMap.of(\"tests.OnlyPrimitivesFactory\", \"expected/OnlyPrimitivesFactory.java\"));\n  }\n\n  @Test\n  public void defaultPackage() {\n    goldenTest(\n        ImmutableList.of(\"good/DefaultPackage.java\"),\n        ImmutableMap.of(\"DefaultPackageFactory\", \"expected/DefaultPackageFactory.java\"));\n  }\n\n  @Test\n  public void generics() {\n    goldenTest(\n        ImmutableList.of(\"good/Generics.java\"),\n        ImmutableMap.of(\n            \"tests.Generics_FooImplFactory\",\n            \"expected/Generics_FooImplFactory.java\",\n            \"tests.Generics_ExplicitFooImplFactory\",\n            \"expected/Generics_ExplicitFooImplFactory.java\",\n            \"tests.Generics_FooImplWithClassFactory\",\n            \"expected/Generics_FooImplWithClassFactory.java\"));\n  }\n\n  @Test\n  public void parameterAnnotations() {\n    goldenTest(\n        ImmutableList.of(\"good/ParameterAnnotations.java\"),\n        ImmutableMap.of(\n            \"tests.ParameterAnnotationsFactory\", \"expected/ParameterAnnotationsFactory.java\"));\n  }\n\n  @Test\n  public void customAnnotations() {\n    goldenTest(\n        ImmutableList.of(\"good/CustomAnnotations.java\"),\n        ImmutableMap.of(\n            \"tests.CustomAnnotationsFactory\", \"expected/CustomAnnotationsFactory.java\"));\n  }\n\n  private JavaFileObject loadExpectedFile(String resourceName) {\n    try {\n      List<String> sourceLines = Resources.readLines(Resources.getResource(resourceName), UTF_8);\n      rewriteImports(sourceLines);\n      return JavaFileObjects.forSourceLines(\n          resourceName.replace('/', '.').replace(\".java\", \"\"), sourceLines);\n    } catch (IOException e) {\n      throw new UncheckedIOException(e);\n    }\n  }\n\n  private static boolean isJavaxAnnotationProcessingGeneratedAvailable() {\n    return SourceVersion.latestSupported().compareTo(SourceVersion.RELEASE_8) > 0;\n  }\n\n  private void rewriteImports(List<String> sourceLines) {\n    int i = 0;\n    int firstImport = Integer.MAX_VALUE;\n    int lastImport = -1;\n    for (String line : sourceLines) {\n      if (line.startsWith(\"import \") && !line.startsWith(\"import static \")) {\n        firstImport = min(firstImport, i);\n        lastImport = max(lastImport, i);\n      }\n      i++;\n    }\n    if (lastImport >= 0) {\n      List<String> importLines = sourceLines.subList(firstImport, lastImport + 1);\n      if (!isJavaxAnnotationProcessingGeneratedAvailable()) {\n        importLines.replaceAll(\n            line ->\n                line.startsWith(\"import javax.annotation.processing.Generated;\")\n                    ? \"import javax.annotation.Generated;\"\n                    : line);\n      }\n      if (config.expectedPackage.equals(InjectPackage.JAKARTA)) {\n        importLines.replaceAll(line -> line.replace(\"javax.inject\", \"jakarta.inject\"));\n      }\n      Collections.sort(importLines);\n    }\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/bad/AnnotationsToApplyMultiple.java",
    "content": "/*\n * Copyright 2023 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\n\n@AutoFactory.AnnotationsToApply\n@interface This {\n  SuppressWarnings suppressWarnings() default @SuppressWarnings(\"Immutable\");\n}\n\n@AutoFactory.AnnotationsToApply\n@interface That {\n  SuppressWarnings suppressWarnings() default @SuppressWarnings(\"Immutable\");\n}\n\n@This\n@That\n@AutoFactory\nfinal class AnnotationsToApplyMultiple {}\n"
  },
  {
    "path": "factory/src/test/resources/bad/AnnotationsToApplyNotAnnotations.java",
    "content": "/*\n * Copyright 2023 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.errorprone.annotations.Immutable;\n\n@AutoFactory.AnnotationsToApply\n@interface ImmutableAndSuppressWarnings {\n  Immutable immutable() default @Immutable;\n\n  SuppressWarnings suppressWarnings() default @SuppressWarnings(\"Immutable\");\n\n  int whatIsThis() default 23;\n\n  Immutable[] andWhatIsThis() default {};\n}\n\n@ImmutableAndSuppressWarnings(suppressWarnings = @SuppressWarnings({\"unchecked\", \"Immutable\"}))\n@AutoFactory\nfinal class AnnotationsToApplyNotAnnotations {}\n"
  },
  {
    "path": "factory/src/test/resources/bad/AnnotationsToApplyRepeated.java",
    "content": "/*\n * Copyright 2023 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\n\n@AutoFactory.AnnotationsToApply\n@interface ReallySuppressWarnings {\n  SuppressWarnings suppressWarnings() default @SuppressWarnings(\"Immutable\");\n\n  SuppressWarnings suppressWarningsSomeMore() default @SuppressWarnings(\"Immutable\");\n}\n\n@ReallySuppressWarnings\n@AutoFactory\nfinal class AnnotationsToApplyMultiple {}\n"
  },
  {
    "path": "factory/src/test/resources/bad/EnumSupertype.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport java.util.concurrent.TimeUnit;\n\n@AutoFactory(extending = TimeUnit.class)\nfinal class InterfaceSupertype {}\n"
  },
  {
    "path": "factory/src/test/resources/bad/FactoryExtendingAbstractClassWithConstructorParams.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport tests.FactoryExtendingAbstractClassWithConstructorParams.AbstractFactory;\n\n@AutoFactory(extending = AbstractFactory.class)\nfinal class FactoryExtendingAbstractClassWithConstructorParams {\n  abstract static class AbstractFactory {\n    protected AbstractFactory(Object obj) {}\n\n    abstract FactoryExtendingAbstractClassWithConstructorParams newInstance();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/bad/FinalSupertype.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\n\n@AutoFactory(extending = Boolean.class)\nfinal class InterfaceSupertype {}\n"
  },
  {
    "path": "factory/src/test/resources/bad/InterfaceSupertype.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\n\n@AutoFactory(extending = Runnable.class)\nfinal class InterfaceSupertype {}\n"
  },
  {
    "path": "factory/src/test/resources/bad/InvalidCustomName.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\n\n@AutoFactory(className = \"SillyFactory!\")\nfinal class InvalidCustomName {}\n"
  },
  {
    "path": "factory/src/test/resources/bad/MixedFinals.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\n\nfinal class MixedFinals {\n  @AutoFactory(allowSubclasses = false)\n  MixedFinals() {}\n\n  @AutoFactory(allowSubclasses = true)\n  MixedFinals(String s) {}\n\n  @AutoFactory(allowSubclasses = true)\n  MixedFinals(String s, Integer i) {}\n}\n"
  },
  {
    "path": "factory/src/test/resources/bad/ProvidedButNoAutoFactory.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.Provided;\n\nfinal class ProvidedButNoAutoFactory {\n  ProvidedButNoAutoFactory(Object a, @Provided Object b) {}\n}\n"
  },
  {
    "path": "factory/src/test/resources/bad/ProvidedOnMethodParameter.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.Provided;\n\nfinal class ProvidedOnMethodParameter {\n  void blah(Object a, @Provided Object b) {}\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/CheckerFrameworkNullableFactory.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport java.util.Map;\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\nimport javax.inject.Provider;\nimport org.checkerframework.checker.nullness.compatqual.NullableDecl;\nimport org.checkerframework.checker.nullness.compatqual.NullableType;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class CheckerFrameworkNullableFactory {\n\n  private final Provider<String> java_lang_StringProvider;\n\n  private final Provider<Map.@NullableType Entry<?, ?>> providedNestedNullableTypeProvider;\n\n  @Inject\n  CheckerFrameworkNullableFactory(\n      Provider<String> java_lang_StringProvider,\n      Provider<Map.@NullableType Entry<?, ?>> providedNestedNullableTypeProvider) {\n    this.java_lang_StringProvider = checkNotNull(java_lang_StringProvider, 1, 2);\n    this.providedNestedNullableTypeProvider =\n        checkNotNull(providedNestedNullableTypeProvider, 2, 2);\n  }\n\n  CheckerFrameworkNullable create(\n      @NullableDecl String nullableDecl,\n      @NullableType String nullableType,\n      Map.@NullableType Entry<?, ?> nestedNullableType) {\n    return new CheckerFrameworkNullable(\n        nullableDecl,\n        java_lang_StringProvider.get(),\n        nullableType,\n        java_lang_StringProvider.get(),\n        nestedNullableType,\n        providedNestedNullableTypeProvider.get());\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/ClassUsingQualifierWithArgsFactory.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\nimport javax.inject.Provider;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class ClassUsingQualifierWithArgsFactory {\n  private final Provider<String> providedDepAProvider;\n\n  @Inject\n  ClassUsingQualifierWithArgsFactory(\n      @QualifierWithArgs(name = \"Fred\", count = 3) Provider<String> providedDepAProvider) {\n    this.providedDepAProvider = checkNotNull(providedDepAProvider, 1, 1);\n  }\n\n  ClassUsingQualifierWithArgs create() {\n    return new ClassUsingQualifierWithArgs(checkNotNull(providedDepAProvider.get(), 1, 1));\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/ConstructorAnnotatedFactory.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\nimport javax.inject.Provider;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class ConstructorAnnotatedFactory {\n  private final Provider<Object> objProvider;\n\n  @Inject\n  ConstructorAnnotatedFactory(Provider<Object> objProvider) {\n    this.objProvider = checkNotNull(objProvider, 1, 1);\n  }\n\n  ConstructorAnnotated create() {\n    return new ConstructorAnnotated();\n  }\n\n  ConstructorAnnotated create(String s) {\n    return new ConstructorAnnotated(checkNotNull(s, 1, 1));\n  }\n\n  ConstructorAnnotated create(int i) {\n    return new ConstructorAnnotated(checkNotNull(objProvider.get(), 1, 2), i);\n  }\n\n  ConstructorAnnotated create(char c) {\n    return new ConstructorAnnotated(checkNotNull(objProvider.get(), 1, 2), c);\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/ConstructorAnnotatedNonFinalFactory.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\nimport javax.inject.Provider;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nclass ConstructorAnnotatedNonFinalFactory {\n  private final Provider<Object> objProvider;\n\n  @Inject\n  ConstructorAnnotatedNonFinalFactory(Provider<Object> objProvider) {\n    this.objProvider = checkNotNull(objProvider, 1, 1);\n  }\n\n  ConstructorAnnotatedNonFinal create() {\n    return new ConstructorAnnotatedNonFinal();\n  }\n\n  ConstructorAnnotatedNonFinal create(String s) {\n    return new ConstructorAnnotatedNonFinal(checkNotNull(s, 1, 1));\n  }\n\n  ConstructorAnnotatedNonFinal create(int i) {\n    return new ConstructorAnnotatedNonFinal(checkNotNull(objProvider.get(), 1, 2), i);\n  }\n\n  ConstructorAnnotatedNonFinal create(char c) {\n    return new ConstructorAnnotatedNonFinal(checkNotNull(objProvider.get(), 1, 2), c);\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/ConstructorAnnotatedThrowsFactory.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport java.io.IOException;\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\nimport javax.inject.Provider;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class ConstructorAnnotatedThrowsFactory {\n  private final Provider<Object> objProvider;\n\n  @Inject\n  ConstructorAnnotatedThrowsFactory(Provider<Object> objProvider) {\n    this.objProvider = checkNotNull(objProvider, 1, 1);\n  }\n\n  ConstructorAnnotatedThrows create() throws IOException, InterruptedException {\n    return new ConstructorAnnotatedThrows();\n  }\n\n  ConstructorAnnotatedThrows create(String s) {\n    return new ConstructorAnnotatedThrows(checkNotNull(s, 1, 1));\n  }\n\n  ConstructorAnnotatedThrows create(int i) throws IOException {\n    return new ConstructorAnnotatedThrows(checkNotNull(objProvider.get(), 1, 2), i);\n  }\n\n  ConstructorAnnotatedThrows create(char c) throws InterruptedException {\n    return new ConstructorAnnotatedThrows(checkNotNull(objProvider.get(), 1, 2), c);\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/CustomAnnotationsFactory.java",
    "content": "/*\n * Copyright 2023 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.errorprone.annotations.Immutable;\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\n@Immutable\n@SuppressWarnings({\"unchecked\", \"Immutable\"})\nfinal class CustomAnnotationsFactory {\n  @Inject\n  CustomAnnotationsFactory() {}\n\n  CustomAnnotations create() {\n    return new CustomAnnotations();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/CustomNamedFactory.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class CustomNamedFactory {\n  @Inject\n  CustomNamedFactory() {}\n\n  SimpleClassCustomName create() {\n    return new SimpleClassCustomName();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/CustomNullableFactory.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\nimport javax.inject.Provider;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class CustomNullableFactory {\n\n  private final Provider<Object> objectProvider;\n\n  @Inject\n  CustomNullableFactory(Provider<Object> objectProvider) {\n    this.objectProvider = checkNotNull(objectProvider, 1, 1);\n  }\n\n  CustomNullable create(@CustomNullable.Nullable String string) {\n    return new CustomNullable(string, objectProvider.get());\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/DefaultPackageFactory.java",
    "content": "/*\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\npublic final class DefaultPackageFactory {\n  @Inject\n  public DefaultPackageFactory() {}\n\n  public DefaultPackage create() {\n    return new DefaultPackage();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/FactoryExtendingAbstractClassFactory.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class FactoryExtendingAbstractClassFactory\n    extends FactoryExtendingAbstractClass.AbstractFactory {\n  @Inject\n  FactoryExtendingAbstractClassFactory() {}\n\n  FactoryExtendingAbstractClass create() {\n    return new FactoryExtendingAbstractClass();\n  }\n\n  @Override\n  public FactoryExtendingAbstractClass newInstance() {\n    return create();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/FactoryExtendingAbstractClassThrowsFactory.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport java.io.IOException;\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class FactoryExtendingAbstractClassThrowsFactory\n    extends FactoryExtendingAbstractClassThrows.AbstractFactory {\n  @Inject\n  FactoryExtendingAbstractClassThrowsFactory() {}\n\n  FactoryExtendingAbstractClassThrows create() throws IOException, InterruptedException {\n    return new FactoryExtendingAbstractClassThrows();\n  }\n\n  @Override\n  public FactoryExtendingAbstractClassThrows newInstance() throws Exception {\n    return create();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/FactoryImplementingCreateMethod_ConcreteClassFactory.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport java.util.List;\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class FactoryImplementingCreateMethod_ConcreteClassFactory\n    implements FactoryImplementingCreateMethod.FactoryInterfaceWithCreateMethod {\n\n  @Inject\n  FactoryImplementingCreateMethod_ConcreteClassFactory() {}\n\n  @Override\n  public FactoryImplementingCreateMethod.ConcreteClass create() {\n    return new FactoryImplementingCreateMethod.ConcreteClass();\n  }\n\n  @Override\n  public FactoryImplementingCreateMethod.ConcreteClass create(int aDifferentArgumentName) {\n    return new FactoryImplementingCreateMethod.ConcreteClass(aDifferentArgumentName);\n  }\n\n  @Override\n  public FactoryImplementingCreateMethod.ConcreteClass create(\n      List<Integer> genericWithDifferentArgumentName) {\n    return new FactoryImplementingCreateMethod.ConcreteClass(\n        checkNotNull(genericWithDifferentArgumentName, 1, 1));\n  }\n\n  FactoryImplementingCreateMethod.ConcreteClass create(int a, boolean b) {\n    return new FactoryImplementingCreateMethod.ConcreteClass(a, b);\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/FactoryImplementingGenericInterfaceExtensionFactory.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\nimport javax.inject.Provider;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class FactoryImplementingGenericInterfaceExtensionFactory\n    implements FactoryImplementingGenericInterfaceExtension.MyFactory {\n  private final Provider<String> sProvider;\n\n  @Inject\n  FactoryImplementingGenericInterfaceExtensionFactory(Provider<String> sProvider) {\n    this.sProvider = checkNotNull(sProvider, 1, 1);\n  }\n\n  FactoryImplementingGenericInterfaceExtension create(Integer i) {\n    return new FactoryImplementingGenericInterfaceExtension(\n        checkNotNull(sProvider.get(), 1, 2), checkNotNull(i, 2, 2));\n  }\n\n  @Override\n  public FactoryImplementingGenericInterfaceExtension make(Integer arg) {\n    return create(arg);\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/Generics_ExplicitFooImplFactory.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\nimport javax.inject.Provider;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class Generics_ExplicitFooImplFactory<M extends Generics.Bar>\n    implements Generics.FooFactory<M> {\n  private final Provider<M> unusedProvider;\n\n  @Inject\n  Generics_ExplicitFooImplFactory(Provider<M> unusedProvider) {\n    this.unusedProvider = checkNotNull(unusedProvider, 1, 1);\n  }\n\n  @Override\n  public Generics.ExplicitFooImpl<M> create() {\n    return new Generics.ExplicitFooImpl<M>(checkNotNull(unusedProvider.get(), 1, 1));\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/Generics_FooImplFactory.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class Generics_FooImplFactory<M extends Generics.Bar> implements Generics.FooFactory<M> {\n  @Inject\n  Generics_FooImplFactory() {}\n\n  @Override\n  public Generics.FooImpl<M> create() {\n    return new Generics.FooImpl<M>();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/Generics_FooImplWithClassFactory.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class Generics_FooImplWithClassFactory<M extends Generics.Bar>\n    extends Generics.FooFactoryClass<M> {\n  @Inject\n  Generics_FooImplWithClassFactory() {}\n\n  @Override\n  public Generics.FooImplWithClass<M> create() {\n    return new Generics.FooImplWithClass<M>();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/MixedDepsImplementingInterfacesFactory.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\nimport javax.inject.Provider;\n\n/**\n * @author Gregory Kick\n */\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class MixedDepsImplementingInterfacesFactory\n    implements MixedDepsImplementingInterfaces.FromInt,\n        MixedDepsImplementingInterfaces.FromObject,\n        MixedDepsImplementingInterfaces.MarkerA,\n        MixedDepsImplementingInterfaces.MarkerB {\n  private final Provider<String> sProvider;\n\n  @Inject\n  MixedDepsImplementingInterfacesFactory(Provider<String> sProvider) {\n    this.sProvider = checkNotNull(sProvider, 1, 1);\n  }\n\n  MixedDepsImplementingInterfaces create(int i) {\n    return new MixedDepsImplementingInterfaces(checkNotNull(sProvider.get(), 1, 2), i);\n  }\n\n  MixedDepsImplementingInterfaces create(Object o) {\n    return new MixedDepsImplementingInterfaces(checkNotNull(o, 1, 1));\n  }\n\n  @Override\n  public MixedDepsImplementingInterfaces fromInt(int i) {\n    return create(i);\n  }\n\n  @Override\n  public MixedDepsImplementingInterfaces fromObject(Object o) {\n    return create(o);\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/MultipleFactoriesConflictingParameterNamesFactory.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\nimport javax.inject.Provider;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class MultipleFactoriesConflictingParameterNamesFactory {\n\n  private final Provider<String> stringProvider;\n  private final Provider<Object> java_lang_ObjectProvider;\n  private final Provider<String> stringProvider2;\n  private final Provider<Object> _tests_AQualifier_java_lang_ObjectProvider;\n\n  @Inject\n  MultipleFactoriesConflictingParameterNamesFactory(\n      Provider<String> stringProvider,\n      Provider<Object> java_lang_ObjectProvider,\n      @AQualifier Provider<String> stringProvider2,\n      @AQualifier Provider<Object> _tests_AQualifier_java_lang_ObjectProvider) {\n    this.stringProvider = checkNotNull(stringProvider, 1, 4);\n    this.java_lang_ObjectProvider = checkNotNull(java_lang_ObjectProvider, 2, 4);\n    this.stringProvider2 = checkNotNull(stringProvider2, 3, 4);\n    this._tests_AQualifier_java_lang_ObjectProvider =\n        checkNotNull(_tests_AQualifier_java_lang_ObjectProvider, 4, 4);\n  }\n\n  MultipleFactoriesConflictingParameterNames create(Object unused) {\n    return new MultipleFactoriesConflictingParameterNames(\n        checkNotNull(stringProvider.get(), 1, 4),\n        checkNotNull(java_lang_ObjectProvider.get(), 2, 4),\n        java_lang_ObjectProvider,\n        checkNotNull(unused, 4, 4));\n  }\n\n  MultipleFactoriesConflictingParameterNames create() {\n    return new MultipleFactoriesConflictingParameterNames(\n        checkNotNull(stringProvider2.get(), 1, 3),\n        checkNotNull(_tests_AQualifier_java_lang_ObjectProvider.get(), 2, 3),\n        _tests_AQualifier_java_lang_ObjectProvider);\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/MultipleFactoriesImplementingInterface_ClassAFactory.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class MultipleFactoriesImplementingInterface_ClassAFactory\n    implements MultipleFactoriesImplementingInterface.Base.Factory {\n  @Inject\n  MultipleFactoriesImplementingInterface_ClassAFactory() {}\n\n  MultipleFactoriesImplementingInterface.ClassA create() {\n    return new MultipleFactoriesImplementingInterface.ClassA();\n  }\n\n  @Override\n  public MultipleFactoriesImplementingInterface.ClassA abstractNonDefaultCreate() {\n    return create();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/MultipleFactoriesImplementingInterface_ClassBFactory.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class MultipleFactoriesImplementingInterface_ClassBFactory\n    implements MultipleFactoriesImplementingInterface.Base.Factory {\n  @Inject\n  MultipleFactoriesImplementingInterface_ClassBFactory() {}\n\n  MultipleFactoriesImplementingInterface.ClassB create() {\n    return new MultipleFactoriesImplementingInterface.ClassB();\n  }\n\n  @Override\n  public MultipleFactoriesImplementingInterface.ClassB abstractNonDefaultCreate() {\n    return create();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/MultipleProvidedParamsSameKeyFactory.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\nimport javax.inject.Provider;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class MultipleProvidedParamsSameKeyFactory {\n  private final Provider<String> java_lang_StringProvider;\n\n  @Inject\n  MultipleProvidedParamsSameKeyFactory(Provider<String> java_lang_StringProvider) {\n    this.java_lang_StringProvider = checkNotNull(java_lang_StringProvider, 1, 1);\n  }\n\n  MultipleProvidedParamsSameKey create() {\n    return new MultipleProvidedParamsSameKey(\n        checkNotNull(java_lang_StringProvider.get(), 1, 5),\n        checkNotNull(java_lang_StringProvider.get(), 2, 5),\n        java_lang_StringProvider.get(),\n        java_lang_StringProvider,\n        java_lang_StringProvider);\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/NestedClassCustomNamedFactory.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class NestedClassCustomNamedFactory {\n  @Inject\n  NestedClassCustomNamedFactory() {}\n\n  NestedClasses.SimpleNestedClassWithCustomFactory create() {\n    return new NestedClasses.SimpleNestedClassWithCustomFactory();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/NestedClasses_SimpleNestedClassFactory.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class NestedClasses_SimpleNestedClassFactory {\n  @Inject\n  NestedClasses_SimpleNestedClassFactory() {}\n\n  NestedClasses.SimpleNestedClass create() {\n    return new NestedClasses.SimpleNestedClass();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/OnlyPrimitivesFactory.java",
    "content": "/*\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class OnlyPrimitivesFactory {\n  @Inject\n  OnlyPrimitivesFactory() {}\n\n  OnlyPrimitives create(int i, long l) {\n    return new OnlyPrimitives(i, l);\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/ParameterAnnotationsFactory.java",
    "content": "/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\nimport javax.inject.Provider;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class ParameterAnnotationsFactory {\n  private final Provider<@ParameterAnnotations.NullableType String> fooProvider;\n\n  @Inject\n  ParameterAnnotationsFactory(Provider<@ParameterAnnotations.NullableType String> fooProvider) {\n    this.fooProvider = checkNotNull(fooProvider, 1, 1);\n  }\n\n  ParameterAnnotations create(\n      @ParameterAnnotations.NullableParameter Integer bar,\n      @ParameterAnnotations.Nullable Long baz,\n      @ParameterAnnotations.NullableType Thread buh,\n      @ParameterAnnotations.NullableParameterAndType String quux) {\n    return new ParameterAnnotations(\n        checkNotNull(fooProvider.get(), 1, 5),\n        checkNotNull(bar, 2, 5),\n        baz,\n        checkNotNull(buh, 4, 5),\n        checkNotNull(quux, 5, 5));\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/ProviderArgumentToCreateMethodFactory.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\nimport javax.inject.Provider;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class ProviderArgumentToCreateMethodFactory\n    implements ProviderArgumentToCreateMethod.CustomCreator {\n  @Inject\n  ProviderArgumentToCreateMethodFactory() {}\n\n  ProviderArgumentToCreateMethod create(Provider<String> stringProvider) {\n    return new ProviderArgumentToCreateMethod(checkNotNull(stringProvider, 1, 1));\n  }\n\n  @Override\n  public ProviderArgumentToCreateMethod newInstance(Provider<String> stringProvider) {\n    return create(stringProvider);\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/PublicClassFactory.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\npublic final class PublicClassFactory {\n  @Inject\n  public PublicClassFactory() {}\n\n  public PublicClass create() {\n    return new PublicClass();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/SimpleClassFactory.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class SimpleClassFactory {\n  @Inject\n  SimpleClassFactory() {}\n\n  SimpleClass create() {\n    return new SimpleClass();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/SimpleClassImplementingMarkerFactory.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport java.util.RandomAccess;\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class SimpleClassImplementingMarkerFactory implements RandomAccess {\n  @Inject\n  SimpleClassImplementingMarkerFactory() {}\n\n  SimpleClassImplementingMarker create() {\n    return new SimpleClassImplementingMarker();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/SimpleClassImplementingSimpleInterfaceFactory.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class SimpleClassImplementingSimpleInterfaceFactory\n    implements SimpleClassImplementingSimpleInterface.SimpleInterface {\n  @Inject\n  SimpleClassImplementingSimpleInterfaceFactory() {}\n\n  SimpleClassImplementingSimpleInterface create() {\n    return new SimpleClassImplementingSimpleInterface();\n  }\n\n  @Override\n  public SimpleClassImplementingSimpleInterface newInstance() {\n    return create();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/SimpleClassMixedDepsFactory.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\nimport javax.inject.Provider;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class SimpleClassMixedDepsFactory {\n  private final Provider<String> providedDepAProvider;\n\n  @Inject\n  SimpleClassMixedDepsFactory(@AQualifier Provider<String> providedDepAProvider) {\n    this.providedDepAProvider = checkNotNull(providedDepAProvider, 1, 1);\n  }\n\n  SimpleClassMixedDeps create(String depB) {\n    return new SimpleClassMixedDeps(\n        checkNotNull(providedDepAProvider.get(), 1, 2), checkNotNull(depB, 2, 2));\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/SimpleClassNonFinalFactory.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nclass SimpleClassNonFinalFactory {\n  @Inject\n  SimpleClassNonFinalFactory() {}\n\n  SimpleClassNonFinal create() {\n    return new SimpleClassNonFinal();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/SimpleClassNullableParametersFactory.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.Nullable;\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\nimport javax.inject.Provider;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class SimpleClassNullableParametersFactory {\n  private final Provider<String> providedNullableProvider;\n\n  private final Provider<String> providedQualifiedNullableProvider;\n\n  @Inject\n  SimpleClassNullableParametersFactory(\n      Provider<String> providedNullableProvider,\n      @BQualifier Provider<String> providedQualifiedNullableProvider) {\n    this.providedNullableProvider = checkNotNull(providedNullableProvider, 1, 2);\n    this.providedQualifiedNullableProvider = checkNotNull(providedQualifiedNullableProvider, 2, 2);\n  }\n\n  SimpleClassNullableParameters create(\n      @Nullable String nullable, @Nullable @AQualifier String qualifiedNullable) {\n    return new SimpleClassNullableParameters(\n        nullable,\n        qualifiedNullable,\n        providedNullableProvider.get(),\n        providedQualifiedNullableProvider.get());\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/SimpleClassPassedDepsFactory.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class SimpleClassPassedDepsFactory {\n  @Inject\n  SimpleClassPassedDepsFactory() {}\n\n  SimpleClassPassedDeps create(String depA, String depB) {\n    return new SimpleClassPassedDeps(checkNotNull(depA, 1, 2), checkNotNull(depB, 2, 2));\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/SimpleClassProvidedDepsFactory.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\nimport javax.inject.Provider;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class SimpleClassProvidedDepsFactory {\n  private final Provider<Integer> providedPrimitiveAProvider;\n  private final Provider<Integer> providedPrimitiveBProvider;\n  private final Provider<String> providedDepAProvider;\n  private final Provider<String> providedDepBProvider;\n\n  @Inject\n  SimpleClassProvidedDepsFactory(\n      @AQualifier Provider<Integer> providedPrimitiveAProvider,\n      @BQualifier Provider<Integer> providedPrimitiveBProvider,\n      @AQualifier Provider<String> providedDepAProvider,\n      @BQualifier Provider<String> providedDepBProvider) {\n    this.providedPrimitiveAProvider = checkNotNull(providedPrimitiveAProvider, 1, 4);\n    this.providedPrimitiveBProvider = checkNotNull(providedPrimitiveBProvider, 2, 4);\n    this.providedDepAProvider = checkNotNull(providedDepAProvider, 3, 4);\n    this.providedDepBProvider = checkNotNull(providedDepBProvider, 4, 4);\n  }\n\n  SimpleClassProvidedDeps create() {\n    return new SimpleClassProvidedDeps(\n        checkNotNull(providedPrimitiveAProvider.get(), 1, 4),\n        checkNotNull(providedPrimitiveBProvider.get(), 2, 4),\n        checkNotNull(providedDepAProvider.get(), 3, 4),\n        checkNotNull(providedDepBProvider.get(), 4, 4));\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/SimpleClassProvidedProviderDepsFactory.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\nimport javax.inject.Provider;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class SimpleClassProvidedProviderDepsFactory {\n  private final Provider<String> providedDepAProvider;\n  private final Provider<String> providedDepBProvider;\n\n  @Inject\n  SimpleClassProvidedProviderDepsFactory(\n      @AQualifier Provider<String> providedDepAProvider,\n      @BQualifier Provider<String> providedDepBProvider) {\n    this.providedDepAProvider = checkNotNull(providedDepAProvider, 1, 2);\n    this.providedDepBProvider = checkNotNull(providedDepBProvider, 2, 2);\n  }\n\n  SimpleClassProvidedProviderDeps create() {\n    return new SimpleClassProvidedProviderDeps(providedDepAProvider, providedDepBProvider);\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/SimpleClassThrowsFactory.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport java.io.IOException;\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class SimpleClassThrowsFactory {\n  @Inject\n  SimpleClassThrowsFactory() {}\n\n  SimpleClassThrows create() throws IOException, InterruptedException {\n    return new SimpleClassThrows();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/expected/SimpleClassVarargsFactory.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport javax.annotation.processing.Generated;\nimport javax.inject.Inject;\n\n@Generated(\n    value = \"com.google.auto.factory.processor.AutoFactoryProcessor\",\n    comments = \"https://github.com/google/auto/tree/main/factory\"\n    )\nfinal class SimpleClassVarargsFactory implements SimpleClassVarargs.InterfaceWithVarargs {\n  @Inject\n  SimpleClassVarargsFactory() {}\n\n  SimpleClassVarargs create(String... args) {\n    return new SimpleClassVarargs(checkNotNull(args, 1, 1));\n  }\n\n  @Override\n  public SimpleClassVarargs build(String... args) {\n    return create(args);\n  }\n\n  private static <T> T checkNotNull(T reference, int argumentNumber, int argumentCount) {\n    if (reference == null) {\n      throw new NullPointerException(\n          \"@AutoFactory method argument is null but is not marked @Nullable. Argument \"\n              + argumentNumber\n              + \" of \"\n              + argumentCount);\n    }\n    return reference;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/CheckerFrameworkNullable.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.Provided;\nimport java.util.Map;\nimport org.checkerframework.checker.nullness.compatqual.NullableDecl;\nimport org.checkerframework.checker.nullness.compatqual.NullableType;\n\n@AutoFactory\nfinal class CheckerFrameworkNullable {\n\n  CheckerFrameworkNullable(\n      @NullableDecl String nullableDecl,\n      @Provided @NullableDecl String providedNullableDecl,\n      @NullableType String nullableType,\n      @Provided @NullableType String providedNullableType,\n      Map.@NullableType Entry<?, ?> nestedNullableType,\n      @Provided Map.@NullableType Entry<?, ?> providedNestedNullableType) {}\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/ClassUsingQualifierWithArgs.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.Provided;\n\n/**\n * @author Justine Tunney\n */\n@AutoFactory\n@SuppressWarnings(\"unused\")\nfinal class ClassUsingQualifierWithArgs {\n  private final String providedDepA;\n\n  ClassUsingQualifierWithArgs(\n      @Provided @QualifierWithArgs(name = \"Fred\", count = 3) String providedDepA) {\n    this.providedDepA = providedDepA;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/ConstructorAnnotated.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.Provided;\n\nfinal class ConstructorAnnotated {\n  @AutoFactory\n  ConstructorAnnotated() {}\n\n  ConstructorAnnotated(Object obj) {}\n\n  @AutoFactory\n  ConstructorAnnotated(String s) {}\n\n  @AutoFactory\n  ConstructorAnnotated(@Provided Object obj, int i) {}\n\n  @AutoFactory\n  ConstructorAnnotated(@Provided Object obj, char c) {}\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/ConstructorAnnotatedNonFinal.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.Provided;\n\nfinal class ConstructorAnnotatedNonFinal {\n  @AutoFactory(allowSubclasses = true)\n  ConstructorAnnotatedNonFinal() {}\n\n  ConstructorAnnotatedNonFinal(Object obj) {}\n\n  @AutoFactory(allowSubclasses = true)\n  ConstructorAnnotatedNonFinal(String s) {}\n\n  @AutoFactory(allowSubclasses = true)\n  ConstructorAnnotatedNonFinal(@Provided Object obj, int i) {}\n\n  @AutoFactory(allowSubclasses = true)\n  ConstructorAnnotatedNonFinal(@Provided Object obj, char c) {}\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/ConstructorAnnotatedThrows.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.Provided;\nimport java.io.IOException;\n\nfinal class ConstructorAnnotatedThrows {\n  @AutoFactory\n  ConstructorAnnotatedThrows() throws IOException, InterruptedException {}\n\n  ConstructorAnnotatedThrows(Object obj) {}\n\n  @AutoFactory\n  ConstructorAnnotatedThrows(String s) {}\n\n  @AutoFactory\n  ConstructorAnnotatedThrows(@Provided Object obj, int i) throws IOException {}\n\n  @AutoFactory\n  ConstructorAnnotatedThrows(@Provided Object obj, char c) throws InterruptedException {}\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/CustomAnnotations.java",
    "content": "/*\n * Copyright 2023 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.errorprone.annotations.Immutable;\n\n@AutoFactory.AnnotationsToApply\n@interface ImmutableAndSuppressWarnings {\n  Immutable immutable() default @Immutable;\n\n  SuppressWarnings suppressWarnings() default @SuppressWarnings(\"Immutable\");\n}\n\n@ImmutableAndSuppressWarnings(suppressWarnings = @SuppressWarnings({\"unchecked\", \"Immutable\"}))\n@AutoFactory\nfinal class CustomAnnotations {}\n"
  },
  {
    "path": "factory/src/test/resources/good/CustomNullable.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.Provided;\n\n@AutoFactory\nfinal class CustomNullable {\n\n  private final String string;\n  private final Object object;\n\n  CustomNullable(\n      @CustomNullable.Nullable String string, @CustomNullable.Nullable @Provided Object object) {\n    this.string = string;\n    this.object = object;\n  }\n\n  @interface Nullable {}\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/DefaultPackage.java",
    "content": "/*\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport com.google.auto.factory.AutoFactory;\n\n@AutoFactory\npublic final class DefaultPackage {}\n"
  },
  {
    "path": "factory/src/test/resources/good/FactoryExtendingAbstractClass.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport tests.FactoryExtendingAbstractClass.AbstractFactory;\n\n@AutoFactory(extending = AbstractFactory.class)\nfinal class FactoryExtendingAbstractClass {\n  abstract static class AbstractFactory {\n    abstract FactoryExtendingAbstractClass newInstance();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/FactoryExtendingAbstractClassThrows.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport java.io.IOException;\nimport tests.FactoryExtendingAbstractClassThrows.AbstractFactory;\n\n@AutoFactory(extending = AbstractFactory.class)\nfinal class FactoryExtendingAbstractClassThrows {\n  FactoryExtendingAbstractClassThrows() throws IOException, InterruptedException {}\n\n  abstract static class AbstractFactory {\n    abstract FactoryExtendingAbstractClassThrows newInstance() throws Exception;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/FactoryExtendingAbstractClassWithMultipleConstructors.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport tests.FactoryExtendingAbstractClassWithMultipleConstructors.AbstractFactory;\n\n@AutoFactory(extending = AbstractFactory.class)\nfinal class FactoryExtendingAbstractClassWithMultipleConstructors {\n  abstract static class AbstractFactory {\n    protected AbstractFactory(Object obj) {}\n\n    protected AbstractFactory() {}\n\n    abstract FactoryExtendingAbstractClassWithMultipleConstructors newInstance();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/FactoryImplementingCreateMethod.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport java.util.List;\n\nfinal class FactoryImplementingCreateMethod {\n\n  interface Interface {}\n\n  interface FactoryInterfaceWithCreateMethod {\n    Interface create();\n\n    Interface create(int a);\n\n    Interface create(List<Integer> generic);\n  }\n\n  @AutoFactory(implementing = FactoryInterfaceWithCreateMethod.class)\n  static class ConcreteClass implements Interface {\n    // Will generate a method with a signature that matches one from the interface.\n    ConcreteClass() {}\n\n    // Will generate a method with a signature that matches one from the interface.\n    ConcreteClass(int aDifferentArgumentName) {}\n\n    // Will generate a method with a signature that matches one from the interface.\n    ConcreteClass(List<Integer> genericWithDifferentArgumentName) {}\n\n    ConcreteClass(int a, boolean b) {}\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/FactoryImplementingGenericInterfaceExtension.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.Provided;\n\nclass FactoryImplementingGenericInterfaceExtension {\n\n  @AutoFactory(implementing = MyFactory.class)\n  FactoryImplementingGenericInterfaceExtension(@Provided String s, Integer i) {}\n\n  interface MyFactory\n      extends GenericFactory<FactoryImplementingGenericInterfaceExtension, Integer> {}\n\n  interface GenericFactory<T, S> {\n    T make(S arg);\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/Generics.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.Provided;\n\nclass Generics {\n  interface Bar {}\n\n  interface Foo<M extends Bar> {}\n\n  interface FooFactory<M extends Bar> {\n    Foo<M> create();\n  }\n\n  // The generated FooImplFactory should also have an <M extends Bar> type parameter, so we can\n  // have FooImplFactory<M extends Bar> implements FooFactory<M>.\n  @AutoFactory(implementing = FooFactory.class)\n  static final class FooImpl<M extends Bar> implements Foo<M> {\n    FooImpl() {}\n  }\n\n  // The generated ExplicitFooImplFactory should have an <M extends Bar> type parameter, which\n  // serves both for FooFactory<M> and for Provider<M> in the constructor.\n  @AutoFactory(implementing = FooFactory.class)\n  static final class ExplicitFooImpl<M extends Bar> implements Foo<M> {\n    ExplicitFooImpl(@Provided M unused) {}\n  }\n\n  abstract static class FooFactoryClass<M extends Bar> {\n    abstract Foo<M> create();\n  }\n\n  @AutoFactory(extending = FooFactoryClass.class)\n  static final class FooImplWithClass<M extends Bar> implements Foo<M> {}\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/MixedDepsImplementingInterfaces.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.Provided;\n\n/**\n * @author Gregory Kick\n */\nfinal class MixedDepsImplementingInterfaces {\n  @AutoFactory(implementing = {FromInt.class, MarkerA.class})\n  MixedDepsImplementingInterfaces(@Provided String s, int i) {}\n\n  @AutoFactory(implementing = {FromObject.class, MarkerB.class})\n  MixedDepsImplementingInterfaces(Object o) {}\n\n  interface FromInt {\n    MixedDepsImplementingInterfaces fromInt(int i);\n  }\n\n  interface FromObject {\n    MixedDepsImplementingInterfaces fromObject(Object o);\n  }\n\n  interface MarkerA {}\n\n  interface MarkerB {}\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/MultipleFactoriesConflictingParameterNames.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.Provided;\nimport javax.inject.Provider;\n\nclass MultipleFactoriesConflictingParameterNames {\n\n  @AutoFactory\n  MultipleFactoriesConflictingParameterNames(\n      @Provided String string,\n      @Provided Object duplicatedKey_nameDoesntMatter,\n      @Provided Provider<Object> duplicatedKeyProvider_nameDoesntMatter,\n      // used to disambiguate with the second constructor since qualifiers aren't part of the type\n      // system\n      Object unused) {}\n\n  @AutoFactory\n  MultipleFactoriesConflictingParameterNames(\n      @Provided @AQualifier String string,\n      @Provided @AQualifier Object qualifiedDuplicatedKey_nameDoesntMatter,\n      @Provided @AQualifier Provider<Object> qualifiedDuplicatedKeyProvider_nameDoesntMatter) {}\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/MultipleFactoriesImplementingInterface.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\n\nclass MultipleFactoriesImplementingInterface {\n  static interface Base {\n    static interface Factory {\n      public abstract Base abstractNonDefaultCreate();\n    }\n  }\n\n  @AutoFactory(implementing = Base.Factory.class)\n  static class ClassA implements Base {}\n\n  @AutoFactory(implementing = Base.Factory.class)\n  static class ClassB implements Base {}\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/MultipleProvidedParamsSameKey.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.Provided;\nimport javax.annotation.Nullable;\nimport javax.inject.Provider;\n\n@AutoFactory\nfinal class MultipleProvidedParamsSameKey {\n  private final String one;\n  private final String two;\n  private final String three;\n  private final Provider<String> providerOne;\n  private final Provider<String> providerTwo;\n\n  public MultipleProvidedParamsSameKey(\n      @Provided String one,\n      @Provided String two,\n      @Nullable @Provided String three,\n      @Provided Provider<String> providerOne,\n      @Provided Provider<String> providerTwo) {\n    this.one = one;\n    this.two = two;\n    this.three = three;\n    this.providerOne = providerOne;\n    this.providerTwo = providerTwo;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/NestedClasses.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\n\nfinal class NestedClasses {\n\n  @AutoFactory\n  static final class SimpleNestedClass {}\n\n  @AutoFactory(className = \"NestedClassCustomNamedFactory\")\n  static final class SimpleNestedClassWithCustomFactory {}\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/OnlyPrimitives.java",
    "content": "/*\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\n\n/**\n * @author Ron Shapiro\n */\n@AutoFactory\nfinal class OnlyPrimitives {\n  OnlyPrimitives(int i, long l) {}\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/ParameterAnnotations.java",
    "content": "/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport static java.lang.annotation.ElementType.PARAMETER;\nimport static java.lang.annotation.ElementType.TYPE_USE;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.Provided;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\n@AutoFactory\nfinal class ParameterAnnotations {\n  @Retention(RUNTIME)\n  @Target(PARAMETER)\n  @interface NullableParameter {}\n\n  // We have special treatment of @Nullable; make sure it doesn't get copied twice.\n  @Retention(RUNTIME)\n  @Target(PARAMETER)\n  @interface Nullable {}\n\n  @Retention(RUNTIME)\n  @Target(TYPE_USE)\n  @interface NullableType {}\n\n  @Retention(RUNTIME)\n  @Target({PARAMETER, TYPE_USE})\n  @interface NullableParameterAndType {}\n\n  ParameterAnnotations(\n      @Provided @NullableParameter @NullableType String foo,\n      @NullableParameter Integer bar,\n      @Nullable Long baz,\n      @NullableType Thread buh,\n      @NullableParameterAndType String quux) {}\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/ProviderArgumentToCreateMethod.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport javax.inject.Provider;\n\n@AutoFactory(implementing = ProviderArgumentToCreateMethod.CustomCreator.class)\nfinal class ProviderArgumentToCreateMethod {\n  private final Provider<String> stringProvider;\n\n  ProviderArgumentToCreateMethod(Provider<String> stringProvider) {\n    this.stringProvider = stringProvider;\n  }\n\n  interface CustomCreator {\n    ProviderArgumentToCreateMethod newInstance(Provider<String> stringProvider);\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/PublicClass.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\n\n@AutoFactory\npublic final class PublicClass {}\n"
  },
  {
    "path": "factory/src/test/resources/good/SimpleClass.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\n\n@AutoFactory\nfinal class SimpleClass {}\n"
  },
  {
    "path": "factory/src/test/resources/good/SimpleClassCustomName.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\n\n@AutoFactory(className = \"CustomNamedFactory\")\nfinal class SimpleClassCustomName {}\n"
  },
  {
    "path": "factory/src/test/resources/good/SimpleClassImplementingMarker.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport java.util.RandomAccess;\n\n@AutoFactory(implementing = RandomAccess.class)\nclass SimpleClassImplementingMarker {}\n"
  },
  {
    "path": "factory/src/test/resources/good/SimpleClassImplementingSimpleInterface.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport tests.SimpleClassImplementingSimpleInterface.SimpleInterface;\n\n@AutoFactory(implementing = SimpleInterface.class)\nfinal class SimpleClassImplementingSimpleInterface {\n  interface SimpleInterface {\n    SimpleClassImplementingSimpleInterface newInstance();\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/SimpleClassMixedDeps.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.Provided;\n\n/**\n * @author Gregory Kick\n */\n@AutoFactory\n@SuppressWarnings(\"unused\")\nfinal class SimpleClassMixedDeps {\n  private final String providedDepA;\n  private final String depB;\n\n  SimpleClassMixedDeps(@Provided @AQualifier String providedDepA, String depB) {\n    this.providedDepA = providedDepA;\n    this.depB = depB;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/SimpleClassNonFinal.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\n\n@AutoFactory(allowSubclasses = true)\nfinal class SimpleClassNonFinal {}\n"
  },
  {
    "path": "factory/src/test/resources/good/SimpleClassNullableParameters.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.Provided;\nimport javax.annotation.Nullable;\n\n@AutoFactory\n@SuppressWarnings(\"unused\")\nfinal class SimpleClassNullableParameters {\n  @Nullable private final String nullable;\n  @Nullable private final String qualifiedNullable;\n  @Nullable private final String providedNullable;\n  @Nullable private final String providedQualifiedNullable;\n\n  // TODO(ronshapiro): with Java 8, test Provider<@Nullable String> parameters and provider fields\n  SimpleClassNullableParameters(\n      @Nullable String nullable,\n      @Nullable @AQualifier String qualifiedNullable,\n      @Nullable @Provided String providedNullable,\n      @Nullable @Provided @BQualifier String providedQualifiedNullable) {\n    this.nullable = nullable;\n    this.qualifiedNullable = qualifiedNullable;\n    this.providedNullable = providedNullable;\n    this.providedQualifiedNullable = providedQualifiedNullable;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/SimpleClassPassedDeps.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\n\n/**\n * @author Gregory Kick\n */\n@AutoFactory\n@SuppressWarnings(\"unused\")\nfinal class SimpleClassPassedDeps {\n  private final String depA;\n  private final String depB;\n\n  SimpleClassPassedDeps(String depA, String depB) {\n    this.depA = depA;\n    this.depB = depB;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/SimpleClassProvidedDeps.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.Provided;\n\n/**\n * @author Gregory Kick\n */\n@AutoFactory\n@SuppressWarnings(\"unused\")\nfinal class SimpleClassProvidedDeps {\n  private final int providedPrimitiveA;\n  private final int providedPrimitiveB;\n  private final String providedDepA;\n  private final String providedDepB;\n\n  SimpleClassProvidedDeps(\n      @Provided @AQualifier int providedPrimitiveA,\n      @Provided @BQualifier int providedPrimitiveB,\n      @Provided @AQualifier String providedDepA,\n      @Provided @BQualifier String providedDepB) {\n    this.providedPrimitiveA = providedPrimitiveA;\n    this.providedPrimitiveB = providedPrimitiveB;\n    this.providedDepA = providedDepA;\n    this.providedDepB = providedDepB;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/SimpleClassProvidedProviderDeps.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport com.google.auto.factory.Provided;\nimport javax.inject.Provider;\n\n/**\n * @author Gregory Kick\n */\n@AutoFactory\n@SuppressWarnings(\"unused\")\nfinal class SimpleClassProvidedProviderDeps {\n  private final Provider<String> providedDepA;\n  private final Provider<String> providedDepB;\n\n  SimpleClassProvidedProviderDeps(\n      @Provided @AQualifier Provider<String> providedDepA,\n      @Provided @BQualifier Provider<String> providedDepB) {\n    this.providedDepA = providedDepA;\n    this.providedDepB = providedDepB;\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/SimpleClassThrows.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\nimport java.io.IOException;\n\n@AutoFactory\nfinal class SimpleClassThrows {\n  SimpleClassThrows() throws IOException, InterruptedException {}\n}\n"
  },
  {
    "path": "factory/src/test/resources/good/SimpleClassVarargs.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport com.google.auto.factory.AutoFactory;\n\n@AutoFactory(implementing = SimpleClassVarargs.InterfaceWithVarargs.class)\nfinal class SimpleClassVarargs {\n  private final String[] args;\n\n  SimpleClassVarargs(String... args) {\n    this.args = args;\n  }\n\n  interface InterfaceWithVarargs {\n    SimpleClassVarargs build(String... args);\n  }\n}\n"
  },
  {
    "path": "factory/src/test/resources/support/AQualifier.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.Retention;\nimport javax.inject.Qualifier;\n\n/**\n * @author Gregory Kick\n */\n@Documented\n@Qualifier\n@Retention(RUNTIME)\n@interface AQualifier {}\n"
  },
  {
    "path": "factory/src/test/resources/support/BQualifier.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.Retention;\nimport javax.inject.Qualifier;\n\n/**\n * @author Gregory Kick\n */\n@Documented\n@Qualifier\n@Retention(RUNTIME)\n@interface BQualifier {}\n"
  },
  {
    "path": "factory/src/test/resources/support/QualifierWithArgs.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage tests;\n\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.Retention;\nimport javax.inject.Qualifier;\n\n/**\n * @author Justine Tunney\n */\n@Documented\n@Qualifier\n@Retention(RUNTIME)\n@interface QualifierWithArgs {\n  String name();\n\n  int count();\n}\n"
  },
  {
    "path": "service/README.md",
    "content": "# AutoService\n\nA configuration/metadata generator for java.util.ServiceLoader-style service\nproviders\n\n## AutoWhat‽\n\n[Java][java] annotation processors and other systems use\n[java.util.ServiceLoader][sl] to register implementations of well-known types\nusing META-INF metadata. However, it is easy for a developer to forget to update\nor correctly specify the service descriptors. \\\nAutoService generates this metadata for the developer, for any class annotated\nwith `@AutoService`, avoiding typos, providing resistance to errors from\nrefactoring, etc.\n\n## Example\n\nSay you have:\n\n```java\npackage foo.bar;\n\nimport com.google.auto.service.AutoService;\nimport javax.annotation.processing.Processor;\n\n@AutoService(Processor.class)\nfinal class MyProcessor implements Processor {\n  // …\n}\n```\n\nAutoService will generate the file\n`META-INF/services/javax.annotation.processing.Processor` in the output classes\nfolder. The file will contain:\n\n```\nfoo.bar.MyProcessor\n```\n\nIn the case of javax.annotation.processing.Processor, if this metadata file is\nincluded in a jar, and that jar is on javac's classpath, then `javac` will\nautomatically load it, and include it in its normal annotation processing\nenvironment. Other users of java.util.ServiceLoader may use the infrastructure\nto different ends, but this metadata will provide auto-loading appropriately.\n\n## Getting Started\n\nYou will need `auto-service-annotations-${version}.jar` in your compile-time\nclasspath, and you will need `auto-service-${version}.jar` in your\nannotation-processor classpath.\n\nIn Maven, you can write:\n\n```xml\n<dependencies>\n  <dependency>\n    <groupId>com.google.auto.service</groupId>\n    <artifactId>auto-service-annotations</artifactId>\n    <version>${auto-service.version}</version>\n  </dependency>\n</dependencies>\n\n...\n\n<plugins>\n  <plugin>\n    <artifactId>maven-compiler-plugin</artifactId>\n    <configuration>\n      <annotationProcessorPaths>\n        <path>\n          <groupId>com.google.auto.service</groupId>\n          <artifactId>auto-service</artifactId>\n          <version>${auto-service.version}</version>\n        </path>\n      </annotationProcessorPaths>\n    </configuration>\n  </plugin>\n</plugins>\n```\n\nPrevious versions of these instructions suggested an alternative configuration,\nwhere the `com.google.auto.service:auto-service` dependency itself was an\n`optional` dependency. We no longer recommend that configuration. (It may pull\nunnecessary classes into your runtime classpath, and it may produce\n[warnings or errors][JDK-8321319] under recent versions of Java.)\n\n[JDK-8321319]: https://bugs.openjdk.org/browse/JDK-8321319\n\n## License\n\n```\nCopyright 2013 Google LLC\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n\n[java]: https://en.wikipedia.org/wiki/Java_(programming_language)\n[sl]: http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html\n"
  },
  {
    "path": "service/annotations/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Copyright 2013 Google LLC\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n-->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>com.google.auto.service</groupId>\n    <artifactId>auto-service-aggregator</artifactId>\n    <version>HEAD-SNAPSHOT</version>\n  </parent>\n\n  <groupId>com.google.auto.service</groupId>\n  <artifactId>auto-service-annotations</artifactId>\n  <version>HEAD-SNAPSHOT</version>\n  <name>AutoService</name>\n  <description>\n    Provider-configuration files for ServiceLoader.\n  </description>\n  <url>https://github.com/google/auto/tree/main/service</url>\n\n  <scm>\n    <url>http://github.com/google/auto</url>\n    <connection>scm:git:git://github.com/google/auto.git</connection>\n    <developerConnection>scm:git:ssh://git@github.com/google/auto.git</developerConnection>\n    <tag>HEAD</tag>\n  </scm>\n\n  <build>\n    <plugins>\n      <plugin>\n        <artifactId>maven-jar-plugin</artifactId>\n        <configuration>\n          <archive>\n            <manifestEntries>\n              <Automatic-Module-Name>com.google.auto.service</Automatic-Module-Name>\n            </manifestEntries>\n          </archive>\n        </configuration>\n      </plugin>\n      <plugin>\n        <artifactId>maven-compiler-plugin</artifactId>\n        <configuration>\n          <!-- disable processing because the definition in META-INF/services breaks javac -->\n          <compilerArgument>-proc:none</compilerArgument>\n          <source>1.8</source>\n          <target>1.8</target>\n        </configuration>\n      </plugin>\n    </plugins>\n  </build>\n</project>\n"
  },
  {
    "path": "service/annotations/src/main/java/com/google/auto/service/AutoService.java",
    "content": "/*\n * Copyright 2008 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.service;\n\nimport static java.lang.annotation.ElementType.TYPE;\nimport static java.lang.annotation.RetentionPolicy.CLASS;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\n/**\n * An annotation for service providers as described in {@link java.util.ServiceLoader}. The\n * annotation processor generates the configuration files that allow the annotated class to be\n * loaded with {@link java.util.ServiceLoader#load(Class)}.\n *\n * <p>The annotated class must conform to the service provider specification. Specifically, it must:\n *\n * <ul>\n *   <li>be a non-inner, non-anonymous, concrete class\n *   <li>have a publicly accessible no-arg constructor\n *   <li>implement the interface type returned by {@code value()}\n * </ul>\n */\n@Documented\n@Retention(CLASS)\n@Target(TYPE)\npublic @interface AutoService {\n  /** Returns the interfaces implemented by this service provider. */\n  Class<?>[] value();\n}\n"
  },
  {
    "path": "service/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Copyright 2013 Google LLC\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n-->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <groupId>com.google.auto.service</groupId>\n  <artifactId>auto-service-aggregator</artifactId>\n  <version>HEAD-SNAPSHOT</version>\n  <name>AutoService Aggregator</name>\n  <description>\n    Aggregator POM for @AutoService\n  </description>\n  <packaging>pom</packaging>\n  <url>https://github.com/google/auto/tree/main/service</url>\n\n  <properties>\n    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n    <java.version>1.8</java.version>\n    <guava.version>33.5.0-jre</guava.version>\n    <truth.version>1.4.5</truth.version>\n  </properties>\n\n  <scm>\n    <url>http://github.com/google/auto</url>\n    <connection>scm:git:git://github.com/google/auto.git</connection>\n    <developerConnection>scm:git:ssh://git@github.com/google/auto.git</developerConnection>\n    <tag>HEAD</tag>\n  </scm>\n\n  <issueManagement>\n    <system>GitHub Issues</system>\n    <url>http://github.com/google/auto/issues</url>\n  </issueManagement>\n\n  <licenses>\n    <license>\n      <name>Apache 2.0</name>\n      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>\n    </license>\n  </licenses>\n\n  <organization>\n    <name>Google LLC</name>\n    <url>http://www.google.com</url>\n  </organization>\n\n  <modules>\n    <module>annotations</module>\n    <module>processor</module>\n  </modules>\n\n  <dependencyManagement>\n    <dependencies>\n      <!-- main dependencies -->\n\n      <dependency>\n        <groupId>com.google.guava</groupId>\n        <artifactId>guava</artifactId>\n        <version>${guava.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>com.google.guava</groupId>\n        <artifactId>guava-gwt</artifactId>\n        <version>${guava.version}</version>\n      </dependency>\n\n      <!-- test dependencies -->\n\n      <dependency>\n        <groupId>com.google.testing.compile</groupId>\n        <artifactId>compile-testing</artifactId>\n        <version>0.23.0</version>\n      </dependency>\n      <dependency>\n        <groupId>com.google.truth</groupId>\n        <artifactId>truth</artifactId>\n        <version>${truth.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>junit</groupId>\n        <artifactId>junit</artifactId>\n        <version>4.13.2</version>\n      </dependency>\n    </dependencies>\n  </dependencyManagement>\n\n  <build>\n    <pluginManagement>\n      <plugins>\n        <plugin>\n          <artifactId>maven-compiler-plugin</artifactId>\n          <version>3.15.0</version>\n          <configuration>\n            <source>${java.version}</source>\n            <target>${java.version}</target>\n            <compilerArgument>-Xlint:all</compilerArgument>\n            <showWarnings>true</showWarnings>\n            <showDeprecation>true</showDeprecation>\n          </configuration>\n        </plugin>\n        <plugin>\n          <artifactId>maven-jar-plugin</artifactId>\n          <version>3.5.0</version>\n        </plugin>\n      </plugins>\n    </pluginManagement>\n\n    <plugins>\n      <plugin>\n        <artifactId>maven-source-plugin</artifactId>\n        <version>3.4.0</version>\n        <executions>\n          <execution>\n            <id>attach-sources</id>\n            <goals>\n              <goal>jar-no-fork</goal>\n            </goals>\n          </execution>\n        </executions>\n      </plugin>\n      <plugin>\n        <artifactId>maven-javadoc-plugin</artifactId>\n        <version>3.12.0</version>\n        <executions>\n          <execution>\n            <id>attach-javadocs</id>\n            <goals>\n              <goal>jar</goal>\n            </goals>\n          </execution>\n        </executions>\n      </plugin>\n      <plugin>\n        <groupId>org.sonatype.central</groupId>\n        <artifactId>central-publishing-maven-plugin</artifactId>\n        <version>0.10.0</version>\n        <extensions>true</extensions>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>sonatype-oss-release</id>\n      <build>\n        <plugins>\n          <plugin>\n            <artifactId>maven-gpg-plugin</artifactId>\n            <version>3.2.8</version>\n            <executions>\n              <execution>\n                <id>sign-artifacts</id>\n                <phase>verify</phase>\n                <goals>\n                  <goal>sign</goal>\n                </goals>\n              </execution>\n            </executions>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "service/processor/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Copyright 2013 Google LLC\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n-->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>com.google.auto.service</groupId>\n    <artifactId>auto-service-aggregator</artifactId>\n    <version>HEAD-SNAPSHOT</version>\n  </parent>\n\n  <groupId>com.google.auto.service</groupId>\n  <artifactId>auto-service</artifactId>\n  <version>HEAD-SNAPSHOT</version>\n  <name>AutoService Processor</name>\n  <description>\n    Provider-configuration files for ServiceLoader.\n  </description>\n  <url>https://github.com/google/auto/tree/main/service</url>\n\n  <scm>\n    <url>http://github.com/google/auto</url>\n    <connection>scm:git:git://github.com/google/auto.git</connection>\n    <developerConnection>scm:git:ssh://git@github.com/google/auto.git</developerConnection>\n    <tag>HEAD</tag>\n  </scm>\n\n  <dependencies>\n    <dependency>\n      <groupId>com.google.auto.service</groupId>\n      <artifactId>auto-service-annotations</artifactId>\n      <version>${project.version}</version>\n    </dependency>\n    <dependency>\n      <groupId>com.google.auto</groupId>\n      <artifactId>auto-common</artifactId>\n      <version>1.2.2</version>\n    </dependency>\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>guava</artifactId>\n    </dependency>\n    <!-- test dependencies -->\n    <dependency>\n      <groupId>com.google.testing.compile</groupId>\n      <artifactId>compile-testing</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>junit</groupId>\n      <artifactId>junit</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.truth</groupId>\n      <artifactId>truth</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-jar-plugin</artifactId>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-compiler-plugin</artifactId>\n        <configuration>\n          <!-- disable processing because the definition in META-INF/services breaks javac -->\n          <compilerArgument>-proc:none</compilerArgument>\n          <source>1.8</source>\n          <target>1.8</target>\n        </configuration>\n      </plugin>\n    </plugins>\n  </build>\n</project>\n"
  },
  {
    "path": "service/processor/src/main/java/com/google/auto/service/processor/AutoServiceProcessor.java",
    "content": "/*\n * Copyright 2008 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.service.processor;\n\nimport static com.google.auto.common.AnnotationMirrors.getAnnotationValue;\nimport static com.google.auto.common.MoreElements.getAnnotationMirror;\nimport static com.google.common.base.Throwables.getStackTraceAsString;\nimport static com.google.common.collect.ImmutableSet.toImmutableSet;\n\nimport com.google.auto.common.MoreElements;\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.service.AutoService;\nimport com.google.common.annotations.VisibleForTesting;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.SortedSetMultimap;\nimport com.google.common.collect.TreeMultimap;\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.SortedSet;\nimport javax.annotation.processing.AbstractProcessor;\nimport javax.annotation.processing.Filer;\nimport javax.annotation.processing.RoundEnvironment;\nimport javax.annotation.processing.SupportedOptions;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.Modifier;\nimport javax.lang.model.element.PackageElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.SimpleAnnotationValueVisitor8;\nimport javax.lang.model.util.Types;\nimport javax.tools.Diagnostic.Kind;\nimport javax.tools.FileObject;\nimport javax.tools.StandardLocation;\n\n/**\n * Processes {@link AutoService} annotations and generates the service provider configuration files\n * described in {@link java.util.ServiceLoader}.\n *\n * <p>Processor Options:\n *\n * <ul>\n *   <li>{@code -Adebug} - turns on debug statements\n *   <li>{@code -Averify=true} - turns on extra verification\n * </ul>\n */\n@SupportedOptions({\"debug\", \"verify\"})\npublic class AutoServiceProcessor extends AbstractProcessor {\n\n  @VisibleForTesting\n  static final String MISSING_SERVICES_ERROR = \"No service interfaces provided for element!\";\n\n  private final List<String> exceptionStacks = Collections.synchronizedList(new ArrayList<>());\n\n  /**\n   * Maps the class names of service provider interfaces to the class names of the concrete classes\n   * which implement them.\n   *\n   * <p>For example, {@code \"com.google.apphosting.LocalRpcService\" ->\n   * \"com.google.apphosting.datastore.LocalDatastoreService\"}\n   */\n  private final SortedSetMultimap<String, String> providers = TreeMultimap.create();\n\n  @Override\n  public ImmutableSet<String> getSupportedAnnotationTypes() {\n    return ImmutableSet.of(AutoService.class.getName());\n  }\n\n  @Override\n  public SourceVersion getSupportedSourceVersion() {\n    return SourceVersion.latestSupported();\n  }\n\n  /**\n   *\n   *\n   * <ol>\n   *   <li>For each class annotated with {@link AutoService}\n   *       <ul>\n   *         <li>Verify the {@link AutoService} interface value is correct\n   *         <li>Categorize the class by its service interface\n   *       </ul>\n   *   <li>For each {@link AutoService} interface\n   *       <ul>\n   *         <li>Create a file named {@code META-INF/services/<interface>}\n   *         <li>For each {@link AutoService} annotated class for this interface\n   *             <ul>\n   *               <li>Create an entry in the file\n   *             </ul>\n   *       </ul>\n   * </ol>\n   */\n  @Override\n  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n    try {\n      processImpl(annotations, roundEnv);\n    } catch (RuntimeException e) {\n      // We don't allow exceptions of any kind to propagate to the compiler\n      String trace = getStackTraceAsString(e);\n      exceptionStacks.add(trace);\n      fatalError(trace);\n    }\n    return false;\n  }\n\n  ImmutableList<String> exceptionStacks() {\n    return ImmutableList.copyOf(exceptionStacks);\n  }\n\n  private void processImpl(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n    if (roundEnv.processingOver()) {\n      generateConfigFiles();\n    } else {\n      processAnnotations(annotations, roundEnv);\n    }\n  }\n\n  private void processAnnotations(\n      Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n\n    Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(AutoService.class);\n\n    log(annotations.toString());\n    log(elements.toString());\n\n    for (Element e : elements) {\n      // TODO(gak): check for error trees?\n      TypeElement providerImplementer = MoreElements.asType(e);\n      AnnotationMirror annotationMirror = getAnnotationMirror(e, AutoService.class).get();\n      ImmutableSet<DeclaredType> providerInterfaces = getValueFieldOfClasses(annotationMirror);\n      if (providerInterfaces.isEmpty()) {\n        error(MISSING_SERVICES_ERROR, e, annotationMirror);\n        continue;\n      }\n      for (DeclaredType providerInterface : providerInterfaces) {\n        TypeElement providerType = MoreTypes.asTypeElement(providerInterface);\n\n        log(\"provider interface: \" + providerType.getQualifiedName());\n        log(\"provider implementer: \" + providerImplementer.getQualifiedName());\n\n        if (checkImplementer(providerImplementer, providerType, annotationMirror)) {\n          providers.put(getBinaryName(providerType), getBinaryName(providerImplementer));\n        } else {\n          String message =\n              \"ServiceProviders must implement their service provider interface. \"\n                  + providerImplementer.getQualifiedName()\n                  + \" does not implement \"\n                  + providerType.getQualifiedName();\n          error(message, e, annotationMirror);\n        }\n      }\n    }\n  }\n\n  private void generateConfigFiles() {\n    Filer filer = processingEnv.getFiler();\n\n    for (String providerInterface : providers.keySet()) {\n      String resourceFile = \"META-INF/services/\" + providerInterface;\n      log(\"Working on resource file: \" + resourceFile);\n      try {\n        SortedSet<String> newServices = providers.get(providerInterface);\n\n        log(\"New service file contents: \" + newServices);\n        FileObject fileObject =\n            filer.createResource(StandardLocation.CLASS_OUTPUT, \"\", resourceFile);\n        try (OutputStream out = fileObject.openOutputStream()) {\n          ServicesFiles.writeServiceFile(newServices, out);\n        }\n        log(\"Wrote to: \" + resourceFile);\n      } catch (IOException e) {\n        fatalError(\"Unable to create \" + resourceFile + \", \" + getStackTraceAsString(e));\n        return;\n      }\n    }\n  }\n\n  /**\n   * Verifies {@link ServiceProvider} constraints on the concrete provider class. Note that these\n   * constraints are enforced at runtime via the ServiceLoader, we're just checking them at compile\n   * time to be extra nice to our users.\n   */\n  private boolean checkImplementer(\n      TypeElement providerImplementer,\n      TypeElement providerType,\n      AnnotationMirror annotationMirror) {\n\n    if (!Boolean.parseBoolean(processingEnv.getOptions().getOrDefault(\"verify\", \"true\"))\n        || suppresses(providerImplementer, \"AutoService\")) {\n      return true;\n    }\n\n    // We check that providerImplementer does indeed inherit from providerType, and that it is not\n    // abstract (an abstract class or interface). For ServiceLoader, we could also check that it has\n    // a public no-arg constructor. But it turns out that people also use AutoService in contexts\n    // where the META-INF/services entries are read by things other than ServiceLoader. Those things\n    // still require the class to exist and inherit from providerType, but they don't necessarily\n    // require a public no-arg constructor.\n    // More background: https://github.com/google/auto/issues/1505.\n\n    Types types = processingEnv.getTypeUtils();\n\n    if (types.isSubtype(providerImplementer.asType(), providerType.asType())) {\n      return checkNotAbstract(providerImplementer, annotationMirror);\n    }\n\n    // Maybe the provider has generic type, but the argument to @AutoService can't be generic.\n    // So we allow that with a warning, which can be suppressed with @SuppressWarnings(\"rawtypes\").\n    // See https://github.com/google/auto/issues/870.\n    if (types.isSubtype(providerImplementer.asType(), types.erasure(providerType.asType()))) {\n      if (!suppresses(providerImplementer, \"rawtypes\")) {\n        warning(\n            \"Service provider \"\n                + providerType\n                + \" is generic, so it can't be named exactly by @AutoService.\"\n                + \" If this is OK, add @SuppressWarnings(\\\"rawtypes\\\").\",\n            providerImplementer,\n            annotationMirror);\n      }\n      return checkNotAbstract(providerImplementer, annotationMirror);\n    }\n\n    String message =\n        \"ServiceProviders must implement their service provider interface. \"\n            + providerImplementer.getQualifiedName()\n            + \" does not implement \"\n            + providerType.getQualifiedName();\n    error(message, providerImplementer, annotationMirror);\n\n    return false;\n  }\n\n  private boolean checkNotAbstract(\n      TypeElement providerImplementer, AnnotationMirror annotationMirror) {\n    if (providerImplementer.getModifiers().contains(Modifier.ABSTRACT)) {\n      error(\n          \"@AutoService can only be applied to a concrete class\",\n          providerImplementer,\n          annotationMirror);\n      return false;\n    }\n    return true;\n  }\n\n  private static boolean suppresses(Element element, String warning) {\n    for (; element != null; element = element.getEnclosingElement()) {\n      SuppressWarnings suppress = element.getAnnotation(SuppressWarnings.class);\n      if (suppress != null && Arrays.asList(suppress.value()).contains(warning)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /**\n   * Returns the binary name of a reference type. For example, {@code com.google.Foo$Bar}, instead\n   * of {@code com.google.Foo.Bar}.\n   */\n  private String getBinaryName(TypeElement element) {\n    return getBinaryNameImpl(element, element.getSimpleName().toString());\n  }\n\n  private String getBinaryNameImpl(TypeElement element, String className) {\n    Element enclosingElement = element.getEnclosingElement();\n\n    if (enclosingElement instanceof PackageElement) {\n      PackageElement pkg = MoreElements.asPackage(enclosingElement);\n      if (pkg.isUnnamed()) {\n        return className;\n      }\n      return pkg.getQualifiedName() + \".\" + className;\n    }\n\n    TypeElement typeElement = MoreElements.asType(enclosingElement);\n    return getBinaryNameImpl(typeElement, typeElement.getSimpleName() + \"$\" + className);\n  }\n\n  /**\n   * Returns the contents of a {@code Class[]}-typed \"value\" field in a given {@code\n   * annotationMirror}.\n   */\n  private ImmutableSet<DeclaredType> getValueFieldOfClasses(AnnotationMirror annotationMirror) {\n    return getAnnotationValue(annotationMirror, \"value\")\n        .accept(\n            new SimpleAnnotationValueVisitor8<ImmutableSet<DeclaredType>, Void>(ImmutableSet.of()) {\n              @Override\n              public ImmutableSet<DeclaredType> visitType(TypeMirror typeMirror, Void v) {\n                // TODO(ronshapiro): class literals may not always be declared types, i.e.\n                // int.class, int[].class\n                return ImmutableSet.of(MoreTypes.asDeclared(typeMirror));\n              }\n\n              @Override\n              public ImmutableSet<DeclaredType> visitArray(\n                  List<? extends AnnotationValue> values, Void v) {\n                return values.stream()\n                    .flatMap(value -> value.accept(this, null).stream())\n                    .collect(toImmutableSet());\n              }\n            },\n            null);\n  }\n\n  private void log(String msg) {\n    if (processingEnv.getOptions().containsKey(\"debug\")) {\n      processingEnv.getMessager().printMessage(Kind.NOTE, msg);\n    }\n  }\n\n  private void warning(String msg, Element element, AnnotationMirror annotation) {\n    processingEnv.getMessager().printMessage(Kind.WARNING, msg, element, annotation);\n  }\n\n  private void error(String msg, Element element, AnnotationMirror annotation) {\n    processingEnv.getMessager().printMessage(Kind.ERROR, msg, element, annotation);\n  }\n\n  private void fatalError(String msg) {\n    processingEnv.getMessager().printMessage(Kind.ERROR, \"FATAL ERROR: \" + msg);\n  }\n}\n"
  },
  {
    "path": "service/processor/src/main/java/com/google/auto/service/processor/ServicesFiles.java",
    "content": "/*\n * Copyright 2008 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.service.processor;\n\nimport static java.nio.charset.StandardCharsets.UTF_8;\n\nimport java.io.BufferedReader;\nimport java.io.BufferedWriter;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.io.OutputStream;\nimport java.io.OutputStreamWriter;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.Set;\n\n/** A helper class for reading and writing Services files. */\nfinal class ServicesFiles {\n  public static final String SERVICES_PATH = \"META-INF/services\";\n\n  private ServicesFiles() {}\n\n  /**\n   * Returns an absolute path to a service file given the class name of the service.\n   *\n   * @param serviceName not {@code null}\n   * @return SERVICES_PATH + serviceName\n   */\n  static String getPath(String serviceName) {\n    return SERVICES_PATH + \"/\" + serviceName;\n  }\n\n  /**\n   * Reads the set of service classes from a service file.\n   *\n   * @param input not {@code null}. Closed after use.\n   * @return a not {@code null Set} of service class names.\n   * @throws IOException\n   */\n  static Set<String> readServiceFile(InputStream input) throws IOException {\n    HashSet<String> serviceClasses = new HashSet<String>();\n    try (BufferedReader reader = new BufferedReader(new InputStreamReader(input, UTF_8))) {\n      String line;\n      while ((line = reader.readLine()) != null) {\n        int commentStart = line.indexOf('#');\n        if (commentStart >= 0) {\n          line = line.substring(0, commentStart);\n        }\n        line = line.trim();\n        if (!line.isEmpty()) {\n          serviceClasses.add(line);\n        }\n      }\n      return serviceClasses;\n    }\n  }\n\n  /**\n   * Writes the set of service class names to a service file.\n   *\n   * @param output not {@code null}. Not closed after use.\n   * @param services a not {@code null Collection} of service class names.\n   * @throws IOException\n   */\n  static void writeServiceFile(Collection<String> services, OutputStream output)\n      throws IOException {\n    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, UTF_8));\n    for (String service : services) {\n      writer.write(service);\n      writer.write('\\n');\n    }\n    writer.flush();\n  }\n}\n"
  },
  {
    "path": "service/processor/src/main/java/com/google/auto/service/processor/package-info.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n/**\n * This package contains the annotation processor that implements the {@link\n * com.google.auto.service.AutoService} API.\n */\npackage com.google.auto.service.processor;\n"
  },
  {
    "path": "service/processor/src/main/resources/META-INF/gradle/incremental.annotation.processors",
    "content": "com.google.auto.service.processor.AutoServiceProcessor,AGGREGATING\n"
  },
  {
    "path": "service/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor",
    "content": "com.google.auto.service.processor.AutoServiceProcessor\n"
  },
  {
    "path": "service/processor/src/test/java/com/google/auto/service/processor/AutoServiceProcessorTest.java",
    "content": "/*\n * Copyright 2008 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.service.processor;\n\nimport static com.google.auto.service.processor.AutoServiceProcessor.MISSING_SERVICES_ERROR;\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.testing.compile.CompilationSubject.assertThat;\n\nimport com.google.common.io.Resources;\nimport com.google.testing.compile.Compilation;\nimport com.google.testing.compile.Compiler;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport javax.tools.StandardLocation;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/** Tests the {@link AutoServiceProcessor}. */\n@RunWith(JUnit4.class)\npublic class AutoServiceProcessorTest {\n  private final Compiler compiler = Compiler.javac().withProcessors(new AutoServiceProcessor());\n\n  @Test\n  public void autoService() {\n    Compilation compilation =\n        compiler.compile(\n            JavaFileObjects.forResource(\"test/SomeService.java\"),\n            JavaFileObjects.forResource(\"test/SomeServiceProvider1.java\"),\n            JavaFileObjects.forResource(\"test/SomeServiceProvider2.java\"),\n            JavaFileObjects.forResource(\"test/Enclosing.java\"),\n            JavaFileObjects.forResource(\"test/AnotherService.java\"),\n            JavaFileObjects.forResource(\"test/AnotherServiceProvider.java\"));\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedFile(StandardLocation.CLASS_OUTPUT, \"META-INF/services/test.SomeService\")\n        .hasContents(\n            Resources.asByteSource(Resources.getResource(\"META-INF/services/test.SomeService\")));\n    assertThat(compilation)\n        .generatedFile(StandardLocation.CLASS_OUTPUT, \"META-INF/services/test.AnotherService\")\n        .hasContents(\n            Resources.asByteSource(Resources.getResource(\"META-INF/services/test.AnotherService\")));\n  }\n\n  @Test\n  public void multiService() {\n    Compilation compilation =\n        compiler.compile(\n            JavaFileObjects.forResource(\"test/SomeService.java\"),\n            JavaFileObjects.forResource(\"test/AnotherService.java\"),\n            JavaFileObjects.forResource(\"test/MultiServiceProvider.java\"));\n    assertThat(compilation).succeededWithoutWarnings();\n    // We have @AutoService({SomeService.class, AnotherService.class}) class MultiServiceProvider.\n    // So we expect META-INF/services/test.SomeService with contents that name MultiServiceProvider\n    // and likewise META-INF/services/test.AnotherService.\n    assertThat(compilation)\n        .generatedFile(StandardLocation.CLASS_OUTPUT, \"META-INF/services/test.SomeService\")\n        .contentsAsUtf8String()\n        .isEqualTo(\"test.MultiServiceProvider\\n\");\n    assertThat(compilation)\n        .generatedFile(StandardLocation.CLASS_OUTPUT, \"META-INF/services/test.AnotherService\")\n        .contentsAsUtf8String()\n        .isEqualTo(\"test.MultiServiceProvider\\n\");\n  }\n\n  @Test\n  public void badMultiService() {\n    Compilation compilation = compiler.compile(JavaFileObjects.forResource(\"test/NoServices.java\"));\n    assertThat(compilation).failed();\n    assertThat(compilation).hadErrorContaining(MISSING_SERVICES_ERROR);\n  }\n\n  @Test\n  public void doesNotImplement_failsByDefault() {\n    Compilation compilation =\n        compiler.compile(JavaFileObjects.forResource(\"test/DoesNotImplement.java\"));\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\"test.DoesNotImplement does not implement test.SomeService\");\n  }\n\n  @Test\n  public void doesNotImplement_succeedsWithVerifyFalse() {\n    Compilation compilation =\n        compiler\n            .withOptions(\"-Averify=false\")\n            .compile(\n                JavaFileObjects.forResource(\"test/DoesNotImplement.java\"),\n                JavaFileObjects.forResource(\"test/SomeService.java\"));\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedFile(StandardLocation.CLASS_OUTPUT, \"META-INF/services/test.SomeService\")\n        .contentsAsUtf8String()\n        .isEqualTo(\"test.DoesNotImplement\\n\");\n  }\n\n  @Test\n  public void doesNotImplement_suppressed() {\n    Compilation compilation =\n        compiler.compile(\n            JavaFileObjects.forResource(\"test/DoesNotImplementSuppressed.java\"),\n            JavaFileObjects.forResource(\"test/SomeService.java\"));\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedFile(StandardLocation.CLASS_OUTPUT, \"META-INF/services/test.SomeService\")\n        .contentsAsUtf8String()\n        .isEqualTo(\"test.DoesNotImplementSuppressed\\n\");\n  }\n\n  @Test\n  public void generic() {\n    Compilation compilation =\n        compiler\n            .withOptions(\"-Averify=false\")\n            .compile(\n                JavaFileObjects.forResource(\"test/GenericService.java\"),\n                JavaFileObjects.forResource(\"test/GenericServiceProvider.java\"));\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedFile(StandardLocation.CLASS_OUTPUT, \"META-INF/services/test.GenericService\")\n        .contentsAsUtf8String()\n        .isEqualTo(\"test.GenericServiceProvider\\n\");\n  }\n\n  @Test\n  public void genericWithNoVerifyOption() {\n    Compilation compilation =\n        compiler.compile(\n            JavaFileObjects.forResource(\"test/GenericService.java\"),\n            JavaFileObjects.forResource(\"test/GenericServiceProvider.java\"));\n    assertThat(compilation).succeeded();\n    assertThat(compilation)\n        .hadWarningContaining(\n            \"Service provider test.GenericService is generic, so it can't be named exactly by\"\n                + \" @AutoService. If this is OK, add @SuppressWarnings(\\\"rawtypes\\\").\");\n  }\n\n  @Test\n  public void genericWithExplicitVerify() {\n    Compilation compilation =\n        compiler\n            .withOptions(\"-Averify=true\")\n            .compile(\n                JavaFileObjects.forResource(\"test/GenericService.java\"),\n                JavaFileObjects.forResource(\"test/GenericServiceProvider.java\"));\n    assertThat(compilation).succeeded();\n    assertThat(compilation)\n        .hadWarningContaining(\n            \"Service provider test.GenericService is generic, so it can't be named exactly by\"\n                + \" @AutoService. If this is OK, add @SuppressWarnings(\\\"rawtypes\\\").\");\n  }\n\n  @Test\n  public void genericWithVerifyOptionAndSuppressWarings() {\n    Compilation compilation =\n        compiler\n            .withOptions(\"-Averify=true\")\n            .compile(\n                JavaFileObjects.forResource(\"test/GenericService.java\"),\n                JavaFileObjects.forResource(\"test/GenericServiceProviderSuppressWarnings.java\"));\n    assertThat(compilation).succeededWithoutWarnings();\n  }\n\n  @Test\n  public void nestedGenericWithVerifyOptionAndSuppressWarnings() {\n    Compilation compilation =\n        compiler\n            .withOptions(\"-Averify=true\")\n            .compile(\n                JavaFileObjects.forResource(\"test/GenericService.java\"),\n                JavaFileObjects.forResource(\"test/EnclosingGeneric.java\"));\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedFile(StandardLocation.CLASS_OUTPUT, \"META-INF/services/test.GenericService\")\n        .contentsAsUtf8String()\n        .isEqualTo(\"test.EnclosingGeneric$GenericServiceProvider\\n\");\n  }\n\n  @Test\n  public void missing() {\n    AutoServiceProcessor processor = new AutoServiceProcessor();\n    Compilation compilation =\n        compiler\n            .withOptions(\"-Averify=true\")\n            .compile(\n                JavaFileObjects.forResource(\n                    \"test/GenericServiceProviderWithMissingServiceClass.java\"));\n    assertThat(compilation).failed();\n    assertThat(processor.exceptionStacks()).isEmpty();\n  }\n\n  @Test\n  public void autoServiceOnInterface() {\n    AutoServiceProcessor processor = new AutoServiceProcessor();\n    JavaFileObject autoServiceOnInterface =\n        JavaFileObjects.forResource(\"test/AutoServiceOnInterface.java\");\n    Compilation compilation =\n        Compiler.javac()\n            .withProcessors(processor)\n            .withOptions(\"-Averify=true\")\n            .compile(autoServiceOnInterface);\n    assertThat(compilation)\n        .hadErrorContaining(\"@AutoService can only be applied to a concrete class\")\n        .inFile(autoServiceOnInterface)\n        .onLineContaining(\"@AutoService\");\n    assertThat(processor.exceptionStacks()).isEmpty();\n  }\n\n  @Test\n  public void autoServiceOnAbstractClass() {\n    AutoServiceProcessor processor = new AutoServiceProcessor();\n    JavaFileObject autoServiceOnAbstractClass =\n        JavaFileObjects.forResource(\"test/AutoServiceOnAbstractClass.java\");\n    Compilation compilation =\n        Compiler.javac()\n            .withProcessors(processor)\n            .withOptions(\"-Averify=true\")\n            .compile(autoServiceOnAbstractClass);\n    assertThat(compilation)\n        .hadErrorContaining(\"@AutoService can only be applied to a concrete class\")\n        .inFile(autoServiceOnAbstractClass)\n        .onLineContaining(\"@AutoService\");\n    assertThat(processor.exceptionStacks()).isEmpty();\n  }\n}\n"
  },
  {
    "path": "service/processor/src/test/resources/META-INF/services/test.AnotherService",
    "content": "test.AnotherServiceProvider\n"
  },
  {
    "path": "service/processor/src/test/resources/META-INF/services/test.SomeService",
    "content": "test.Enclosing$NestedSomeServiceProvider\ntest.SomeServiceProvider1\ntest.SomeServiceProvider2\n"
  },
  {
    "path": "service/processor/src/test/resources/test/AnotherService.java",
    "content": "/*\n * Copyright 2008 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage test;\n\ninterface AnotherService {}\n"
  },
  {
    "path": "service/processor/src/test/resources/test/AnotherServiceProvider.java",
    "content": "/*\n * Copyright 2008 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage test;\n\nimport com.google.auto.service.AutoService;\n\n@AutoService(AnotherService.class)\npublic class AnotherServiceProvider implements AnotherService {}\n"
  },
  {
    "path": "service/processor/src/test/resources/test/AutoServiceOnAbstractClass.java",
    "content": "/*\n * Copyright 2023 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage test;\n\nimport com.google.auto.service.AutoService;\n\n@AutoService(SomeService.class)\npublic abstract class AutoServiceOnAbstractClass implements SomeService {}\n"
  },
  {
    "path": "service/processor/src/test/resources/test/AutoServiceOnInterface.java",
    "content": "/*\n * Copyright 2023 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage test;\n\nimport com.google.auto.service.AutoService;\n\n@AutoService(SomeService.class)\npublic interface AutoServiceOnInterface extends SomeService {}\n"
  },
  {
    "path": "service/processor/src/test/resources/test/DoesNotImplement.java",
    "content": "/*\n * Copyright 2023 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage test;\n\nimport com.google.auto.service.AutoService;\n\n@AutoService(SomeService.class)\npublic class DoesNotImplement {}\n"
  },
  {
    "path": "service/processor/src/test/resources/test/DoesNotImplementSuppressed.java",
    "content": "/*\n * Copyright 2023 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage test;\n\nimport com.google.auto.service.AutoService;\n\n@AutoService(SomeService.class)\n@SuppressWarnings(\"AutoService\")\npublic class DoesNotImplementSuppressed {}\n"
  },
  {
    "path": "service/processor/src/test/resources/test/Enclosing.java",
    "content": "/*\n * Copyright 2008 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage test;\n\nimport com.google.auto.service.AutoService;\n\npublic class Enclosing {\n  @AutoService(SomeService.class)\n  public static class NestedSomeServiceProvider implements SomeService {}\n}\n"
  },
  {
    "path": "service/processor/src/test/resources/test/EnclosingGeneric.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage test;\n\nimport com.google.auto.service.AutoService;\n\n/** Test for suppressing warnings about raw types on nested {@code @AutoService} classes. */\n@SuppressWarnings(\"rawtypes\")\npublic final class EnclosingGeneric {\n  /**\n   * This is technically a raw class reference, but should be suppressed by the\n   * {@code @SuppressWarnings} on the enclosing class.\n   */\n  @AutoService(GenericService.class)\n  public class GenericServiceProvider<T> implements GenericService<T> {}\n\n  private EnclosingGeneric() {}\n}\n"
  },
  {
    "path": "service/processor/src/test/resources/test/GenericService.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage test;\n\n/**\n * An interface with a type parameter, which by default will produce a warning with\n * {@code @AutoService} if you compile with {@code -Averify=true}.\n */\npublic interface GenericService<T> {}\n"
  },
  {
    "path": "service/processor/src/test/resources/test/GenericServiceProvider.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage test;\n\nimport com.google.auto.service.AutoService;\n\n/**\n * An implementation of a service with a type parameter, which by default will produce a warning if\n * you compile with {@code -Averify=true}.\n */\n@AutoService(GenericService.class)\npublic class GenericServiceProvider<T> implements GenericService<T> {}\n"
  },
  {
    "path": "service/processor/src/test/resources/test/GenericServiceProviderSuppressWarnings.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage test;\n\nimport com.google.auto.service.AutoService;\n\n/**\n * An implementation of a service with a type parameter, which will not produce a warning even if\n * compiled with {@code -Averify=true}, because of the {@code @SuppressWarnings}.\n */\n@AutoService(GenericService.class)\n@SuppressWarnings(\"rawtypes\")\npublic class GenericServiceProviderSuppressWarnings<T> implements GenericService<T> {}\n"
  },
  {
    "path": "service/processor/src/test/resources/test/GenericServiceProviderWithMissingServiceClass.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage test;\n\nimport com.google.auto.service.AutoService;\n\n/**\n * A service that references a missing class. This is useful for testing that the processor behaves\n * correctly.\n */\n@AutoService(MissingServiceClass.class)\npublic class GenericServiceProviderWithMissingServiceClass<T> implements MissingServiceClass<T> {}\n"
  },
  {
    "path": "service/processor/src/test/resources/test/MultiServiceProvider.java",
    "content": "/*\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage test;\n\nimport com.google.auto.service.AutoService;\n\n@AutoService({SomeService.class, AnotherService.class})\npublic class MultiServiceProvider implements SomeService, AnotherService {}\n"
  },
  {
    "path": "service/processor/src/test/resources/test/NoServices.java",
    "content": "/*\n * Copyright 2008 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage test;\n\nimport com.google.auto.service.AutoService;\n\n@AutoService({})\npublic class NoServices {}\n"
  },
  {
    "path": "service/processor/src/test/resources/test/SomeService.java",
    "content": "/*\n * Copyright 2008 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage test;\n\ninterface SomeService {}\n"
  },
  {
    "path": "service/processor/src/test/resources/test/SomeServiceProvider1.java",
    "content": "/*\n * Copyright 2008 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage test;\n\nimport com.google.auto.service.AutoService;\n\n@AutoService(SomeService.class)\npublic class SomeServiceProvider1 implements SomeService {}\n"
  },
  {
    "path": "service/processor/src/test/resources/test/SomeServiceProvider2.java",
    "content": "/*\n * Copyright 2008 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage test;\n\nimport com.google.auto.service.AutoService;\n\n@AutoService(SomeService.class)\npublic class SomeServiceProvider2 implements SomeService {}\n"
  },
  {
    "path": "util/generate-latest-docs.sh",
    "content": "#!/bin/bash\n\n# Run by GitHub Actions (see .github/workflows/ci.yml)\n\nset -e\n\necho -e \"Publishing javadoc...\\n\"\n\nmvn -f build-pom.xml javadoc:aggregate\nTARGET=\"$(pwd)/target\"\n\ncd $HOME\ngit clone --quiet --branch=gh-pages \"https://x-access-token:${GITHUB_TOKEN}@github.com/google/auto\" gh-pages > /dev/null\n\ncd gh-pages\ngit config --global user.name \"$GITHUB_ACTOR\"\ngit config --global user.email \"$GITHUB_ACTOR@users.noreply.github.com\"\ngit rm -rf api/latest\nmkdir -p api # Just to make mv work if the directory is missing\nmv ${TARGET}/reports/apidocs api/latest\ngit add -A -f api/latest\ngit commit -m \"Latest javadoc on successful CI build auto-pushed to gh-pages\"\ngit push -fq origin gh-pages > /dev/null\n\necho -e \"Published Javadoc to gh-pages.\\n\"\n"
  },
  {
    "path": "util/publish-snapshot-on-commit.sh",
    "content": "#!/bin/bash\n\nset -e\n\nmvn -B dependency:go-offline test clean -U --quiet --fail-never -DskipTests=true -f build-pom.xml\nmvn -B -U deploy -DskipTests=true -f build-pom.xml\n"
  },
  {
    "path": "value/CHANGES.md",
    "content": "# AutoValue Changes\n\n**This document is obsolete.** For details of changes in releases since 1.5,\nsee the [releases page](https://github.com/google/auto/releases) for the Auto\nproject.\n\n## 1.4 → 1.5\n\n### Functional changes\n\n* A workaround for older Eclipse versions has been removed. If you need to use\n  an Eclipse version older than 4.5, you will need to stay on AutoValue 1.4.\n\n* The [retention](https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/Retention.html)\n  of the `@AutoValue` annotation has changed from `SOURCE` to `CLASS`. This\n  means that it is possible for code-analysis tools to tell whether a class is\n  an `@AutoValue`. AutoValue itself uses this to enforce the check that one\n  `@AutoValue` class cannot extend another, even if the classes are compiled\n  separately.\n\n* It is now an error if `@Memoized` is applied to a method not inside an\n  `@AutoValue` class.\n\n* Type annotations are now handled more consistently. If `@Nullable` is a type\n  annotation, a property of type `@Nullable Integer` will have that type used\n  everywhere in the generated code. Associated bugs with nested type\n  annotations, like `Outer.@Inner`, have been fixed.\n\n### Bugs fixed since 1.4.1\n\n* `@Memoized` methods can now throw checked exceptions. Previously this failed\n  because the exceptions were not copied into the `throws` clause of the\n  generated override, so the call to `super.foo()` did not compile.\n\n* The generated `hashCode()` method uses `h = (int) (h ^ longProperty)` rather\n  than `h ^= longProperty` to avoid warnings about loss of precision.\n\n* Annotations are not copied from an abstract method to its implementation if\n  they are not visible from the latter. This can happen if the `@AutoValue`\n  inherits the abstract method from a class or interface in a different package.\n\n## 1.3 → 1.4\n\n*This is the last AutoValue version that compiles and runs on Java 6.* Future\nversions will require at least Java 8 to run. We will continue to generate code\nthat is compatible with Java 7, so AutoValue can be used with `javac -source 7\n-target 7 -bootclasspath <rt.jar-from-jdk7>`, but using the `javac` from jdk8 or\nlater.\n\n### Functional changes\n\n* Builder setters now reject a null parameter immediately unless the\n  corresponding property is `@Nullable`. Previously this check happened at\n  `build()` time, and in some cases didn't happen at all. This is the change\n  that is most likely to affect existing code.\n\n* Added `@Memoized`. A `@Memoized` method will be overridden in the generated\n  `AutoValue_Foo` class to save the value returned the first time it was called\n  and reuse that every other time.\n\n* Generalized support for property builders. Now, in addition to being able to\n  say `immutableListBuilder()` for a property of type `ImmutableList<T>`, you\n  can say `fooBuilder()` for a property of an arbitrary type that has a builder\n  following certain conventions. In particular, you can do this if the type of\n  `foo()` is itself an `@AutoValue` class with a builder. The default value of\n  `foo()`, if `fooBuilder()` is never called, is `fooBuilder().build()`.\n\n* If a property `foo()` or `getFoo()` has a builder method `fooBuilder()` then\n  the property can not now be `@Nullable`. An `ImmutableList`, for example,\n  starts off empty, not null, so `@Nullable` was misleading.\n\n* When an `@AutoValue` class `Foo` has a builder, the generated\n  `AutoValue_Foo.Builder` has a constructor `AutoValue_Foo.Builder(Foo)`. That\n  constructor was never documented and is now private. If you want to make a\n  `Foo.Builder` from a `Foo`, `Foo` should have an abstract method `Builder\n  toBuilder()`.\n\n  This change was necessary so that generalized property-builder support could\n  know whether or not the built class needs to be convertible back into its\n  builder. That's only necessary if there is a `toBuilder()`.\n\n* The Extension API is now a committed API, meaning we no longer warn that it is\n  likely to change incompatibly. A\n  [guide](https://github.com/google/auto/blob/main/value/userguide/extensions.md)\n  gives tips on writing extensions.\n\n* Extensions can now return null rather than generated code. In that case the\n  extension does not generate a class in the AutoValue hierarchy, but it can\n  still do other things like error checking or generating side files.\n\n* Access modifiers like `protected` are copied from builder methods to their\n  implementations, instead of the implementations always being public.\n  Change by @torquestomp.\n\n* AutoAnnotation now precomputes parts of the `hashCode` that are constant\n  because they come from defaulted methods. This avoids warnings about integer\n  overflow from tools that check that.\n\n* If a property is called `oAuth()`, its setter can be called\n  `setOAuth(x)`. Previously it had to be `setoAuth(x)`, which is still allowed.\n\n## Bugs fixed\n\n* AutoAnnotation now correctly handles types like `Class<? extends\n  Annotation>[]`. Previously it would try to create a generic array, which Java\n  doesn't allow. Change by @lukesandberg.\n\n* We guard against spurious exceptions due to a JDK bug in reading resources\n  from jars. (#365)\n\n* We don't propagate an exception if a corrupt jar is found in extension\n  loading.\n\n* AutoValue is ready for Java 9, where public classes are not necessarily\n  accessible, and javax.annotation.Generated is not necessarily present.\n\n* AutoValue now works correctly even if the version of AutoValue in the\n  `-classpath` is older than the one in the `-processorpath`.\n\n* Builders now behave correctly when there is a non-optional property called\n  `missing`. Previously a variable-hiding problem meant that we didn't detect\n  when it wasn't set.\n\n* If `@AutoValue class Foo` has a builder, we always generated two constructors,\n  `Builder()` and `Builder(Foo)`, but we only used the second one if `Foo` had a\n  `toBuilder()` method. Now we only generate that constructor if it is\n  needed. That avoids warnings about unused code.\n\n* `@AutoAnnotation` now works when the annotation and the factory method are in\n  the default (unnamed) package.\n\n## 1.2 → 1.3\n\n### Functional changes\n\n* Support for TYPE_USE `@Nullable`.\n  This is https://github.com/google/auto/pull/293 by @brychcy.\n\n* Restructured the code in AutoValueProcessor for handling extensions, to get\n  rid of warnings about abstract methods when those methods are going to be\n  implemented by an extension, and to fix a bug where extensions would not work\n  right if there was a toBuilder() method. Some of the code in this change is\n  based on https://github.com/google/auto/pull/299 by @rharter.\n\n* Added support for \"optional getters\", where a getter in an AutoValue Builder\n  can have type `Optional<T>` and it will return `Optional.of(x)` where `x` is\n  the value that has been set in the Builder, or `Optional.empty()` if no value\n  has been set.\n\n* In AutoValue builders, added support for setting a property of type\n  `Optional<T>` via a setter with an argument of type `T`.\n\n* Added logic to AutoValue to detect the confusing case where you think you\n  are using JavaBeans conventions (like getFoo()) but you aren't because at\n  least one method isn't.\n\n* Added a README.md describing EscapeVelocity.\n\n### Bugs fixed\n\n* Allow an `@AutoValue.Builder` to extend a parent builder using the `<B extends\n  Builder<B>>` idiom.\n\n* AutoAnnotation now factors in package names when detecting\n  overloads. Previously it treated all annotations with the same SimpleName as\n  being overload attempts.\n\n* Removed an inaccurate javadoc reference, which referred to an\n  artifact from an earlier draft version of the Extensions API. This is\n  https://github.com/google/auto/pull/322 by @lucastsa.\n\n## 1.1 → 1.2\n\n### Functional changes\n\n  * A **provisional** extension API has been introduced. This **will change**\n    in a later release. If you want to use it regardless, see the\n    [AutoValueExtension] class.\n\n  * Properties of primitive array type (e.g. `byte[]`) are no longer cloned\n    when read. If your `@AutoValue` class includes an array property, by default\n    it will get a compiler warning, which can be suppressed with\n    `@SuppressWarnings(\"mutable\")`.\n\n  * An `@AutoValue.Builder` type can now define both the setter and builder\n    methods like so:\n\n    ```\n      ...\n      abstract void setStrings(ImmutableList<String>);\n      abstract ImmutableList.Builder<String> stringsBuilder();\n      ...\n    ```\n    At runtime, if `stringsBuilder()...` is called then it is an error to call\n    `setStrings(...)` afterwards.\n\n  * The classes in the autovalue jar are now shaded with a `$` so they never\n    appear in IDE autocompletion.\n\n  * AutoValue now uses its own implementation of a subset of Apache Velocity,\n    so there will no longer be problems with interference between the Velocity\n    that was bundled with AutoValue and other versions that might be present.\n\n### Bugs fixed\n\n  * Explicit check for nested `@AutoValue` classes being private, or not being\n    static. Otherwise the compiler errors could be hard to understand,\n    especially in IDEs.\n\n  * An Eclipse bug that could occasionally lead to exceptions in the IDE has\n    been fixed (GitHub issue #200).\n\n  * Fixed a bug where AutoValue generated incorrect code if a method with a\n    type parameter was inherited by a class that supplies a concrete type for\n    that parameter. For example `StringIterator implements Iterator<String>`,\n    where the type of `next()` is String, not `T`.\n\n  * In `AutoValueProcessor`, fixed an exception that happened if the same\n    abstract method was inherited from more than one parent (Github Issue #267).\n\n  * AutoValue now works correctly in an environment where\n    `@javax.annotation.Generated` does not exist.\n\n  * Properties marked `@Nullable` now get `@Nullable` on the corresponding\n    constructor parameters in the generated class.\n\n## 1.0 → 1.1\n\n### Functional changes\n\n  * Adds builders to AutoValue. Builders are nested classes annotated with\n    `@AutoValue.Builder`.\n\n  * Annotates constructor parameters with `@Nullable` if the corresponding\n    property methods are `@Nullable`.\n\n  * Changes Maven shading so org.apache.commons is shaded.\n\n  * Copies a `@GwtCompatible` annotation from the `@AutoValue` class to its\n    implementation subclass.\n\n### Bugs fixed\n\n  * Works around a bug in the Eclipse compiler that meant that annotations\n    would be incorrectly copied from `@AutoValue` methods to their\n    implementations.\n\n## 1.0 (Initial Release)\n\n  * Allows automatic generation of value type implementations\n\n    See [the AutoValue User's Guide](userguide/index.md)\n\n\n[AutoValueExtension]: src/main/java/com/google/auto/value/extension/AutoValueExtension.java\n"
  },
  {
    "path": "value/README.md",
    "content": "# AutoValue\n\n*Generated immutable value classes for Java 8+* <br />\n***Kevin Bourrillion, Éamonn McManus*** <br />\n**Google, Inc.**\n\n**Value classes** are extremely common in Java projects. These are classes for\nwhich you want to treat any two instances with suitably equal field values as\ninterchangeable. That's right: we're talking about those classes where you wind\nup implementing `equals`, `hashCode` and `toString` in a bloated, repetitive,\nformulaic yet error-prone fashion.\n\nWriting these methods the first time is not too bad, with the aid of a few\nhelper methods and IDE templates. But once written they continue to burden\nreviewers, editors and future readers. Their wide expanses of boilerplate\nsharply decrease the signal-to-noise ratio of your code... and they love to\nharbor hard-to-spot bugs.\n\nAutoValue provides an easier way to create immutable value classes, with a lot\nless code and less room for error, while **not restricting your freedom** to\ncode almost any aspect of your class exactly the way you want it.\n\nFor more information, consult the [detailed documentation].\n\n**Note:** If you are using Kotlin then its\n[data classes](https://kotlinlang.org/docs/data-classes.html) are usually more\nappropriate than AutoValue. Likewise, if you are using a version of Java that\nhas [records] then those are usually more appropriate. You can still\nuse [AutoBuilder] to make builders for data classes or records.\n\n[detailed documentation]: userguide/index.md\n[records]: userguide/records.md\n[AutoBuilder]: userguide/autobuilder.md\n"
  },
  {
    "path": "value/annotations/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Copyright 2012 Google LLC\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n-->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>com.google.auto.value</groupId>\n    <artifactId>auto-value-parent</artifactId>\n    <version>HEAD-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>auto-value-annotations</artifactId>\n  <version>HEAD-SNAPSHOT</version>\n  <name>AutoValue Annotations</name>\n  <description>\n    Immutable value-type code generation for Java 8+.\n  </description>\n  <url>https://github.com/google/auto/tree/main/value</url>\n\n  <properties>\n    <java.version>1.8</java.version>\n  </properties>\n\n  <scm>\n    <url>http://github.com/google/auto</url>\n    <connection>scm:git:git://github.com/google/auto.git</connection>\n    <developerConnection>scm:git:ssh://git@github.com/google/auto.git</developerConnection>\n    <tag>HEAD</tag>\n  </scm>\n  <build>\n    <sourceDirectory>../src/main/java</sourceDirectory>\n    <plugins>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-compiler-plugin</artifactId>\n        <configuration>\n          <includes>\n            <include>com/google/auto/value/*</include>\n            <include>com/google/auto/value/extension/memoized/*</include>\n            <include>com/google/auto/value/extension/serializable/*</include>\n            <include>com/google/auto/value/extension/toprettystring/*</include>\n          </includes>\n        </configuration>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-jar-plugin</artifactId>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-invoker-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n  <profiles>\n    <profile>\n      <id>disable-java8-doclint</id>\n      <activation>\n        <jdk>[1.8,)</jdk>\n      </activation>\n      <properties>\n        <additionalparam>-Xdoclint:none</additionalparam>\n      </properties>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "value/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Copyright 2012 Google LLC\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n-->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <groupId>com.google.auto.value</groupId>\n  <artifactId>auto-value-parent</artifactId>\n  <version>HEAD-SNAPSHOT</version>\n  <name>AutoValue Parent</name>\n  <description>\n    Immutable value-type code generation for Java 8+.\n  </description>\n  <packaging>pom</packaging>\n  <url>https://github.com/google/auto/tree/main/value</url>\n\n  <properties>\n    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n    <java.version>1.8</java.version>\n    <guava.version>33.5.0-jre</guava.version>\n  </properties>\n\n  <scm>\n    <url>http://github.com/google/auto</url>\n    <connection>scm:git:git://github.com/google/auto.git</connection>\n    <developerConnection>scm:git:ssh://git@github.com/google/auto.git</developerConnection>\n    <tag>HEAD</tag>\n  </scm>\n\n  <issueManagement>\n    <system>GitHub Issues</system>\n    <url>http://github.com/google/auto/issues</url>\n  </issueManagement>\n\n  <licenses>\n    <license>\n      <name>Apache 2.0</name>\n      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>\n    </license>\n  </licenses>\n\n  <organization>\n    <name>Google LLC</name>\n    <url>http://www.google.com</url>\n  </organization>\n\n  <developers>\n    <developer>\n      <id>eamonnmcmanus</id>\n      <name>Éamonn McManus</name>\n      <email>emcmanus@google.com</email>\n      <organization>Google</organization>\n      <organizationUrl>http://www.google.com</organizationUrl>\n      <roles>\n        <role>owner</role>\n        <role>developer</role>\n      </roles>\n      <timezone>-8</timezone>\n    </developer>\n  </developers>\n\n  <modules>\n    <module>annotations</module>\n    <module>processor</module>\n    <module>src/it/functional</module>\n  </modules>\n\n  <dependencyManagement>\n    <dependencies>\n      <!-- main dependencies -->\n\n      <dependency>\n        <groupId>com.google.guava</groupId>\n        <artifactId>guava</artifactId>\n        <version>${guava.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>com.google.guava</groupId>\n        <artifactId>guava-gwt</artifactId>\n        <version>${guava.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>com.squareup</groupId>\n        <artifactId>javapoet</artifactId>\n        <version>1.13.0</version>\n      </dependency>\n\n      <!-- test dependencies -->\n\n      <dependency>\n        <groupId>com.google.code.findbugs</groupId>\n        <artifactId>jsr305</artifactId>\n        <version>3.0.2</version>\n      </dependency>\n      <dependency>\n        <groupId>com.google.guava</groupId>\n        <artifactId>guava-testlib</artifactId>\n        <version>${guava.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>com.google.testing.compile</groupId>\n        <artifactId>compile-testing</artifactId>\n        <version>0.23.0</version>\n      </dependency>\n      <dependency>\n        <groupId>com.google.truth</groupId>\n        <artifactId>truth</artifactId>\n        <version>1.4.5</version>\n      </dependency>\n      <dependency>\n        <groupId>junit</groupId>\n        <artifactId>junit</artifactId>\n        <version>4.13.2</version>\n      </dependency>\n    </dependencies>\n  </dependencyManagement>\n\n  <build>\n    <plugins>\n      <plugin>\n        <artifactId>maven-javadoc-plugin</artifactId>\n        <version>3.12.0</version>\n        <configuration>\n          <failOnError>false</failOnError>\n        </configuration>\n        <executions>\n          <execution>\n            <id>attach-javadocs</id>\n            <goals>\n              <goal>jar</goal>\n            </goals>\n          </execution>\n        </executions>\n      </plugin>\n      <plugin>\n        <artifactId>maven-source-plugin</artifactId>\n        <version>3.4.0</version>\n        <executions>\n          <execution>\n            <id>attach-sources</id>\n            <goals>\n              <goal>jar-no-fork</goal>\n            </goals>\n          </execution>\n        </executions>\n      </plugin>\n      <plugin>\n        <groupId>org.sonatype.central</groupId>\n        <artifactId>central-publishing-maven-plugin</artifactId>\n        <version>0.10.0</version>\n        <extensions>true</extensions>\n      </plugin>\n    </plugins>\n    <pluginManagement>\n      <plugins>\n        <plugin>\n          <artifactId>maven-compiler-plugin</artifactId>\n          <version>3.15.0</version>\n          <configuration>\n            <source>${java.version}</source>\n            <target>${java.version}</target>\n            <compilerArgument>-Xlint:all</compilerArgument>\n            <showWarnings>true</showWarnings>\n            <showDeprecation>true</showDeprecation>\n          </configuration>\n          <executions>\n            <execution>\n              <id>default-testCompile</id>\n              <phase>test-compile</phase>\n              <goals>\n                <goal>testCompile</goal>\n              </goals>\n              <configuration>\n                <testExcludes>\n                  <exclude>${excluded-tests}</exclude>\n                </testExcludes>\n              </configuration>\n            </execution>\n          </executions>\n        </plugin>\n        <plugin>\n          <artifactId>maven-jar-plugin</artifactId>\n          <version>3.5.0</version>\n        </plugin>\n        <plugin>\n          <artifactId>maven-invoker-plugin</artifactId>\n          <version>3.9.1</version>\n          <configuration>\n            <addTestClassPath>true</addTestClassPath>\n            <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>\n            <localRepositoryPath>${project.build.directory}/it-repo</localRepositoryPath>\n            <pomIncludes>\n              <pomInclude>*/pom.xml</pomInclude>\n            </pomIncludes>\n            <streamLogs>true</streamLogs>\n          </configuration>\n          <executions>\n            <execution>\n              <id>integration-test</id>\n              <goals>\n                <goal>install</goal>\n                <goal>run</goal>\n              </goals>\n            </execution>\n          </executions>\n        </plugin>\n        <plugin>\n          <groupId>org.immutables.tools</groupId>\n          <artifactId>maven-shade-plugin</artifactId>\n          <version>4</version>\n        </plugin>\n      </plugins>\n    </pluginManagement>\n  </build>\n  <profiles>\n    <profile>\n      <id>java-11-and-after</id>\n      <activation>\n        <jdk>[11,)</jdk>\n      </activation>\n      <modules>\n        <module>src/it/gwtserializer</module>\n      </modules>\n    </profile>\n    <profile>\n      <id>before-java-17</id>\n      <activation>\n        <jdk>(,17)</jdk>\n      </activation>\n      <properties>\n        <excluded-tests>**/MemoizedTest.java</excluded-tests>\n      </properties>\n    </profile>\n    <profile>\n      <id>sonatype-oss-release</id>\n      <build>\n        <plugins>\n          <plugin>\n            <artifactId>maven-gpg-plugin</artifactId>\n            <version>3.2.8</version>\n            <executions>\n              <execution>\n                <id>sign-artifacts</id>\n                <phase>verify</phase>\n                <goals>\n                  <goal>sign</goal>\n                </goals>\n              </execution>\n            </executions>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "value/processor/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Copyright 2012 Google LLC\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n-->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>com.google.auto.value</groupId>\n    <artifactId>auto-value-parent</artifactId>\n    <version>HEAD-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>auto-value</artifactId>\n  <version>HEAD-SNAPSHOT</version>\n  <name>AutoValue Processor</name>\n  <description>\n    Immutable value-type code generation for Java 8+.\n  </description>\n  <url>https://github.com/google/auto/tree/main/value</url>\n\n  <scm>\n    <url>http://github.com/google/auto</url>\n    <connection>scm:git:git://github.com/google/auto.git</connection>\n    <developerConnection>scm:git:ssh://git@github.com/google/auto.git</developerConnection>\n    <tag>HEAD</tag>\n  </scm>\n\n  <properties>\n    <auto-service.version>1.1.1</auto-service.version>\n    <errorprone.version>2.48.0</errorprone.version>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>com.google.auto</groupId>\n      <artifactId>auto-common</artifactId>\n      <version>1.2.2</version>\n    </dependency>\n    <dependency>\n      <groupId>com.google.auto.service</groupId>\n      <artifactId>auto-service-annotations</artifactId>\n      <version>${auto-service.version}</version>\n    </dependency>\n    <dependency>\n      <groupId>com.google.errorprone</groupId>\n      <artifactId>error_prone_annotations</artifactId>\n      <version>${errorprone.version}</version>\n    </dependency>\n    <dependency>\n      <groupId>com.google.escapevelocity</groupId>\n      <artifactId>escapevelocity</artifactId>\n      <version>1.1</version>\n    </dependency>\n    <dependency>\n      <groupId>net.ltgt.gradle.incap</groupId>\n      <artifactId>incap</artifactId>\n      <version>1.0.0</version>\n    </dependency>\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>guava</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.squareup</groupId>\n      <artifactId>javapoet</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.ow2.asm</groupId>\n      <artifactId>asm</artifactId>\n      <version>9.9.1</version>\n    </dependency>\n    <!-- test dependencies -->\n    <dependency>\n      <groupId>com.google.auto.value</groupId>\n      <artifactId>auto-value-annotations</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>guava-testlib</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>junit</groupId>\n      <artifactId>junit</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.truth</groupId>\n      <artifactId>truth</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.testing.compile</groupId>\n      <artifactId>compile-testing</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.code.findbugs</groupId>\n      <artifactId>jsr305</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.checkerframework</groupId>\n      <artifactId>checker-qual</artifactId>\n      <version>3.54.0</version>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <sourceDirectory>../src/main/java</sourceDirectory>\n    <testSourceDirectory>../src/test/java</testSourceDirectory>\n\n    <resources>\n      <resource>\n        <directory>../src/main/java</directory>\n        <includes>\n          <include>**/*.vm</include>\n        </includes>\n      </resource>\n    </resources>\n    <plugins>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-compiler-plugin</artifactId>\n        <configuration>\n          <includes>\n            <include>com/google/auto/value/processor/**/*.java</include>\n            <include>com/google/auto/value/extension/memoized/processor/**/*.java</include>\n            <include>com/google/auto/value/extension/serializable/processor/**/*.java</include>\n            <include>com/google/auto/value/extension/serializable/serializer/**/*.java</include>\n            <include>com/google/auto/value/extension/toprettystring/processor/**/*.java</include>\n          </includes>\n          <compilerArgs>\n            <!-- This is something of a hack to allow tests to pass. Ideally we would build\n                 TestStringSerializerFactory as a separate artifact, to avoid a problem when it\n                 is built at the same time as @AutoValue classes that might end up finding it.\n                 But by allowing a missing class to be ignored, we avoid crashing if there is a\n                 META-INF/services entry for a class that the compiler has not yet generated. -->\n            <arg>-AallowedMissingSerializableExtensionClasses=.*TestStringSerializerFactory</arg>\n          </compilerArgs>\n          <annotationProcessorPaths>\n            <path>\n              <groupId>com.google.auto.service</groupId>\n              <artifactId>auto-service</artifactId>\n              <version>${auto-service.version}</version>\n            </path>\n            <path>\n              <groupId>net.ltgt.gradle.incap</groupId>\n              <artifactId>incap-processor</artifactId>\n              <version>1.0.0</version>\n            </path>\n          </annotationProcessorPaths>\n        </configuration>\n        <executions>\n          <execution>\n            <id>default-testCompile</id>\n            <configuration>\n              <compilerArgs>\n                <!-- For MemoizeTest. -->\n                <arg>-parameters</arg>\n              </compilerArgs>\n              <annotationProcessorPaths>\n                <path>\n                  <groupId>com.google.auto.value</groupId>\n                  <artifactId>auto-value</artifactId>\n                  <version>${project.version}</version>\n                </path>\n                <path>\n                  <groupId>com.google.auto.service</groupId>\n                  <artifactId>auto-service</artifactId>\n                  <version>${auto-service.version}</version>\n                </path>\n              </annotationProcessorPaths>\n            </configuration>\n          </execution>\n        </executions>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-surefire-plugin</artifactId>\n        <version>3.5.5</version>\n        <configuration>\n          <argLine>${test.jvm.flags}</argLine>\n        </configuration>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-jar-plugin</artifactId>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-invoker-plugin</artifactId>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-shade-plugin</artifactId>\n        <version>3.6.2</version>\n        <executions>\n          <execution>\n            <phase>package</phase>\n            <goals>\n              <goal>shade</goal>\n            </goals>\n            <configuration>\n              <minimizeJar>true</minimizeJar>\n              <relocations>\n                <relocation>\n                  <pattern>com.google</pattern>\n                  <shadedPattern>autovalue.shaded.com.google</shadedPattern>\n                  <excludes>\n                    <exclude>com.google.auto.value.**</exclude>\n                  </excludes>\n                </relocation>\n                <relocation>\n                  <pattern>com.squareup.javapoet</pattern>\n                  <shadedPattern>autovalue.shaded.com.squareup.javapoet</shadedPattern>\n                </relocation>\n                <relocation>\n                  <pattern>net.ltgt.gradle.incap</pattern>\n                  <shadedPattern>autovalue.shaded.net.ltgt.gradle.incap</shadedPattern>\n                </relocation>\n                <relocation>\n                  <pattern>org.checkerframework</pattern>\n                  <shadedPattern>autovalue.shaded.org.checkerframework</shadedPattern>\n                </relocation>\n                <relocation>\n                  <pattern>org.jetbrains</pattern>\n                  <shadedPattern>autovalue.shaded.org.jetbrains</shadedPattern>\n                </relocation>\n                <relocation>\n                  <pattern>org.jspecify</pattern>\n                  <shadedPattern>autovalue.shaded.org.jspecify</shadedPattern>\n                </relocation>\n                <relocation>\n                  <pattern>org.objectweb</pattern>\n                  <shadedPattern>autovalue.shaded.org.objectweb</shadedPattern>\n                </relocation>\n              </relocations>\n            </configuration>\n          </execution>\n        </executions>\n      </plugin>\n    </plugins>\n  </build>\n  <profiles>\n    <profile>\n      <id>disable-java8-doclint</id>\n      <activation>\n        <jdk>[1.8,)</jdk>\n      </activation>\n      <properties>\n        <additionalparam>-Xdoclint:none</additionalparam>\n      </properties>\n    </profile>\n    <profile>\n      <id>open-modules</id>\n      <activation>\n        <jdk>[9,)</jdk>\n      </activation>\n      <properties>\n        <test.jvm.flags>\n          --add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED\n          --add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED\n          --add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED\n          --add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED\n          --add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED\n          --add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED\n        </test.jvm.flags>\n      </properties>\n    </profile>\n    <profile>\n      <id>exclude-module-tests</id>\n      <activation>\n        <jdk>(,9)</jdk>\n      </activation>\n      <build>\n        <plugins>\n          <plugin>\n            <artifactId>maven-compiler-plugin</artifactId>\n            <configuration>\n              <testExcludes>\n                <exclude>**/AutoValueModuleCompilationTest.java</exclude>\n              </testExcludes>\n            </configuration>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "value/src/it/functional/invoker.properties",
    "content": "invoker.goals = clean verify\n\ninvoker.profiles.1 =\ninvoker.profiles.2 = eclipse"
  },
  {
    "path": "value/src/it/functional/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Copyright 2013 Google LLC\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n-->\n<!-- TODO(gak): see if we can manage these dependencies any better -->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>com.google.auto.value</groupId>\n    <artifactId>auto-value-parent</artifactId>\n    <version>HEAD-SNAPSHOT</version>\n    <relativePath>../../../pom.xml</relativePath>\n  </parent>\n  <url>https://github.com/google/auto/tree/main/value</url>\n\n  <groupId>com.google.auto.value.it.functional</groupId>\n  <artifactId>functional</artifactId>\n  <version>HEAD-SNAPSHOT</version>\n  <name>Auto-Value Functional Integration Test</name>\n  <properties>\n    <kotlin.version>2.3.20</kotlin.version>\n  </properties>\n  <dependencies>\n    <dependency>\n      <groupId>com.google.auto.value</groupId>\n      <artifactId>auto-value-annotations</artifactId>\n      <version>${project.version}</version>\n    </dependency>\n    <dependency>\n      <groupId>com.google.auto.service</groupId>\n      <artifactId>auto-service</artifactId>\n      <version>1.1.1</version>\n    </dependency>\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>guava</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.google.code.findbugs</groupId>\n      <artifactId>jsr305</artifactId>\n      <scope>provided</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.gwtproject</groupId>\n      <artifactId>gwt-user</artifactId>\n      <version>2.13.0</version>\n    </dependency>\n    <dependency>\n      <groupId>com.google.auto.value</groupId>\n      <artifactId>auto-value</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>junit</groupId>\n      <artifactId>junit</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>guava-testlib</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.truth</groupId>\n      <artifactId>truth</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.testing.compile</groupId>\n      <artifactId>compile-testing</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>dev.gradleplugins</groupId>\n      <artifactId>gradle-test-kit</artifactId>\n      <version>8.11.1</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.escapevelocity</groupId>\n      <artifactId>escapevelocity</artifactId>\n      <version>1.1</version>\n    </dependency>\n    <dependency>\n      <groupId>org.jetbrains.kotlin</groupId>\n      <artifactId>kotlin-stdlib</artifactId>\n      <version>${kotlin.version}</version>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-jar-plugin</artifactId>\n        <version>3.5.0</version>\n      </plugin>\n      <plugin>\n        <groupId>org.jetbrains.kotlin</groupId>\n        <artifactId>kotlin-maven-plugin</artifactId>\n        <version>${kotlin.version}</version>\n        <executions>\n          <!--\n          The Kotlin configuration here is a bit unusual. JetBrains recommends\n          <https://kotlinlang.org/docs/maven.html#compile-kotlin-and-java-sources>\n          a fairly invasive reconfiguration of the maven-compiler-plugin (which compiles Java)\n          in order to ensure that the Kotlin compiler can run first. In our case, we have just\n          one Kotlin file that a test in Java accesses. So, even though it is in src/test/java,\n          we compile it in the `compile` goal, which means it is available to the Java test sources\n          when they are compiled in the `default-testCompile` goal.\n\n          Currently if you want to use JDK ≥ 16 then you must set\n          JAVA_TOOL_OPTIONS=__illegal-access=permit\n          except the two underscores should be dashes (which XML comments won't allow us to write).\n          This is a bug that will presumably be fixed in a forthcoming version.\n          -->\n          <execution>\n            <id>compile</id>\n            <goals>\n              <goal>compile</goal>\n            </goals>\n            <configuration>\n              <sourceDirs>\n                <sourceDir>${project.basedir}/src/test/java</sourceDir>\n              </sourceDirs>\n            </configuration>\n          </execution>\n        </executions>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-compiler-plugin</artifactId>\n        <version>3.15.0</version>\n        <configuration>\n          <annotationProcessorPaths>\n            <path>\n              <groupId>com.google.auto.value</groupId>\n              <artifactId>auto-value</artifactId>\n              <version>${project.version}</version>\n            </path>\n            <path>\n              <groupId>org.jetbrains.kotlin</groupId>\n              <artifactId>kotlin-metadata-jvm</artifactId>\n              <version>2.3.20</version>\n            </path>\n          </annotationProcessorPaths>\n          <source>${java.specification.version}</source>\n          <target>${java.specification.version}</target>\n          <compilerArgs>\n            <arg>-Xlint:all</arg>\n            <arg>-encoding</arg>\n            <arg>utf8</arg>\n          </compilerArgs>\n          <showWarnings>true</showWarnings>\n          <showDeprecation>true</showDeprecation>\n          <testExcludes combine.children=\"append\" />\n        </configuration>\n      </plugin>\n      <plugin>\n        <groupId>org.sonatype.central</groupId>\n        <artifactId>central-publishing-maven-plugin</artifactId>\n        <configuration>\n          <skipPublishing>true</skipPublishing>\n        </configuration>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-surefire-plugin</artifactId>\n        <version>3.5.5</version>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-failsafe-plugin</artifactId>\n        <version>3.5.5</version>\n        <configuration>\n          <systemPropertyVariables>\n            <autoValueVersion>${project.version}</autoValueVersion>\n          </systemPropertyVariables>\n        </configuration>\n        <executions>\n          <execution>\n            <phase>install</phase>\n            <goals>\n              <goal>integration-test</goal>\n              <goal>verify</goal>\n            </goals>\n          </execution>\n        </executions>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>eclipse</id>\n      <build>\n        <plugins>\n          <plugin>\n            <groupId>org.apache.maven.plugins</groupId>\n            <artifactId>maven-compiler-plugin</artifactId>\n            <version>3.15.0</version>\n            <configuration>\n              <annotationProcessorPaths>\n                <path>\n                  <groupId>com.google.auto.value</groupId>\n                  <artifactId>auto-value</artifactId>\n                  <version>${project.version}</version>\n                </path>\n                <path>\n                  <groupId>org.jetbrains.kotlin</groupId>\n                  <artifactId>kotlin-metadata-jvm</artifactId>\n                  <version>2.3.20</version>\n                </path>\n              </annotationProcessorPaths>\n              <source>${java.specification.version}</source>\n              <target>${java.specification.version}</target>\n              <compilerArgs>\n                <arg>-Xlint:all</arg>\n                <arg>-encoding</arg>\n                <arg>utf8</arg>\n              </compilerArgs>\n              <showWarnings>true</showWarnings>\n              <showDeprecation>true</showDeprecation>\n              <testExcludes combine.children=\"append\" />\n            </configuration>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n\n    <profile>\n      <id>test-with-ecj</id>\n      <activation>\n        <jdk>[11,)</jdk>\n      </activation>\n      <dependencies>\n        <!-- test dependencies -->\n        <dependency>\n          <groupId>org.eclipse.jdt</groupId>\n          <artifactId>ecj</artifactId>\n          <version>3.45.0</version>\n          <scope>test</scope>\n        </dependency>\n      </dependencies>\n    </profile>\n\n    <profile>\n      <id>test-without-ecj</id>\n      <activation>\n        <jdk>(,17)</jdk>\n      </activation>\n      <build>\n        <plugins>\n          <plugin>\n            <artifactId>maven-compiler-plugin</artifactId>\n            <configuration>\n              <testExcludes>\n                <exclude>**/CompileWithEclipseTest.java</exclude>\n              </testExcludes>\n            </configuration>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n\n    <profile>\n      <id>open-modules</id>\n      <activation>\n        <jdk>[9,)</jdk>\n      </activation>\n      <build>\n        <plugins>\n          <plugin>\n            <artifactId>maven-surefire-plugin</artifactId>\n            <configuration>\n              <argLine>\n                --add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED\n                --add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED\n                --add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED\n                --add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED\n                --add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED\n                --add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED\n              </argLine>\n            </configuration>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n\n    <profile>\n      <!-- Before JDK 11, parameter names from already-compiled classes are not reliably available\n           to the compiler even when they are present in class files. Since our Kotlin test file\n           obviously has to be compiled separately from the Java test that uses it,\n           AutoBuilderKotlinTest doesn't pass on earlier JDK versions. -->\n      <id>exclude-separate-compilation-parameter-names</id>\n      <activation>\n        <jdk>(,11)</jdk>\n      </activation>\n      <build>\n        <plugins>\n          <plugin>\n            <artifactId>maven-compiler-plugin</artifactId>\n            <configuration>\n              <testExcludes>\n                <exclude>**/AutoBuilderKotlinTest.java</exclude>\n              </testExcludes>\n            </configuration>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "value/src/it/functional/src/main/java/PackagelessNestedValueType.java",
    "content": "/*\n * Copyright 2012 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport com.google.auto.value.AutoValue;\nimport java.util.Map;\n\n/**\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@SuppressWarnings(\"DefaultPackage\")\npublic class PackagelessNestedValueType {\n  @AutoValue\n  public abstract static class Nested {\n    abstract Map<Integer, String> numberNames();\n\n    public static Nested create(Map<Integer, String> numberNames) {\n      return new AutoValue_PackagelessNestedValueType_Nested(numberNames);\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/main/java/PackagelessValueType.java",
    "content": "/*\n * Copyright 2012 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport com.google.auto.value.AutoValue;\nimport java.util.Map;\nimport javax.annotation.Nullable;\n\n/**\n * Simple package-less value type for tests.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@SuppressWarnings(\"DefaultPackage\")\n@AutoValue\npublic abstract class PackagelessValueType {\n  // The getters here are formatted as an illustration of what getters typically look in real\n  // classes. In particular they have doc comments.\n\n  /**\n   * @return A string that is a nullable string.\n   */\n  @Nullable\n  public abstract String string();\n\n  /**\n   * @return An integer that is an integer.\n   */\n  public abstract int integer();\n\n  /**\n   * @return A non-null map where the keys are strings and the values are longs.\n   */\n  public abstract Map<String, Long> map();\n\n  public static PackagelessValueType create(\n      @Nullable String string, int integer, Map<String, Long> map) {\n    // The subclass AutoValue_PackagelessValueType is created by the annotation processor that is\n    // triggered by the presence of the @AutoValue annotation. It has a constructor for each\n    // of the abstract getter methods here, in order. The constructor stashes the values here\n    // in private final fields, and each method is implemented to return the value of the\n    // corresponding field.\n    return new AutoValue_PackagelessValueType(string, integer, map);\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/main/java/com/google/auto/value/NestedValueType.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value;\n\nimport java.util.Map;\n\n/**\n * @author emcmanus@google.com (Éamonn McManus)\n */\npublic class NestedValueType {\n  @AutoValue\n  public abstract static class Nested {\n    abstract Map<Integer, String> numberNames();\n\n    public static Nested create(Map<Integer, String> numberNames) {\n      return new AutoValue_NestedValueType_Nested(numberNames);\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/main/java/com/google/auto/value/SimpleValueType.java",
    "content": "/*\n * Copyright 2012 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value;\n\nimport java.util.Map;\nimport javax.annotation.Nullable;\n\n/**\n * Simple value type for tests.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@AutoValue\npublic abstract class SimpleValueType {\n  // The getters here are formatted as an illustration of what getters typically look in real\n  // classes. In particular they have doc comments.\n\n  /** Returns a string that is a nullable string. */\n  @Nullable\n  public abstract String string();\n\n  /** Returns an integer that is an integer. */\n  public abstract int integer();\n\n  /** Returns a non-null map where the keys are strings and the values are longs. */\n  public abstract Map<String, Long> map();\n\n  public static SimpleValueType create(\n      @Nullable String string, int integer, Map<String, Long> map) {\n    // The subclass AutoValue_SimpleValueType is created by the annotation processor that is\n    // triggered by the presence of the @AutoValue annotation. It has a constructor for each\n    // of the abstract getter methods here, in order. The constructor stashes the values here\n    // in private final fields, and each method is implemented to return the value of the\n    // corresponding field.\n    return new AutoValue_SimpleValueType(string, integer, map);\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/PackagelessValueTypeTest.java",
    "content": "/*\n * Copyright 2012 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertSame;\n\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.testing.NullPointerTester;\nimport java.util.Map;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class PackagelessValueTypeTest {\n  @Test\n  public void testPackagelessValueType() {\n    final String happy = \"happy\";\n    final int testInt = 23;\n    final Map<String, Long> testMap = ImmutableMap.of(\"happy\", 23L);\n    PackagelessValueType simple = PackagelessValueType.create(happy, testInt, testMap);\n    assertSame(happy, simple.string());\n    assertEquals(testInt, simple.integer());\n    assertSame(testMap, simple.map());\n    assertEquals(\n        \"PackagelessValueType{string=happy, integer=23, map={happy=23}}\", simple.toString());\n    int expectedHashCode = 1;\n    expectedHashCode = (expectedHashCode * 1000003) ^ happy.hashCode();\n    expectedHashCode = (expectedHashCode * 1000003) ^ ((Object) testInt).hashCode();\n    expectedHashCode = (expectedHashCode * 1000003) ^ testMap.hashCode();\n    assertEquals(expectedHashCode, simple.hashCode());\n  }\n\n  @Test\n  public void testNestedValueType() {\n    ImmutableMap<Integer, String> numberNames = ImmutableMap.of(1, \"un\", 2, \"deux\");\n    PackagelessNestedValueType.Nested nested =\n        PackagelessNestedValueType.Nested.create(numberNames);\n    assertEquals(numberNames, nested.numberNames());\n  }\n\n  @Test\n  public void testNull() {\n    NullPointerTester tester = new NullPointerTester();\n    tester.testAllPublicStaticMethods(PackagelessValueType.class);\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/AutoAnnotationDefaultsTest.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value;\n\nimport static org.junit.Assert.assertTrue;\n\nimport com.google.auto.value.enums.MyEnum;\nimport com.google.common.testing.EqualsTester;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.reflect.Method;\nimport java.util.Arrays;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class AutoAnnotationDefaultsTest {\n  @Retention(RetentionPolicy.RUNTIME)\n  @interface EverythingWithDefaults {\n    byte aByte() default 1;\n\n    short aShort() default 2;\n\n    int anInt() default 3;\n\n    long aLong() default Long.MAX_VALUE;\n\n    float aFloat() default Float.MAX_VALUE;\n\n    double aDouble() default -Double.MAX_VALUE;\n\n    char aChar() default '#';\n\n    boolean aBoolean() default true;\n\n    String aString() default \"maybe\\nmaybe not\\n\";\n\n    String spaces() default \"  ( x ) , ( y )\"; // ensure the formatter doesn't eat spaces\n\n    MyEnum anEnum() default MyEnum.TWO;\n\n    byte[] bytes() default {-1, 0, 1};\n\n    short[] shorts() default {-2, 0, 2};\n\n    int[] ints() default {};\n\n    long[] longs() default {-Long.MAX_VALUE};\n\n    float[] floats() default {\n      -Float.MIN_VALUE, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, Float.NaN,\n    };\n\n    double[] doubles() default {\n      -Double.MIN_VALUE, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN,\n    };\n\n    char[] chars() default {'f', '\\n', '\\uffef'};\n\n    boolean[] booleans() default {false, true};\n\n    String[] strings() default {\"\", \"\\uffef\\n\"};\n\n    MyEnum[] enums() default {MyEnum.ONE, MyEnum.TWO};\n  }\n\n  @AutoAnnotation\n  static EverythingWithDefaults newEverythingWithDefaults() {\n    return new AutoAnnotation_AutoAnnotationDefaultsTest_newEverythingWithDefaults();\n  }\n\n  @Test\n  public void testDefaults() throws Exception {\n    @EverythingWithDefaults\n    class Annotated {}\n    EverythingWithDefaults expected = Annotated.class.getAnnotation(EverythingWithDefaults.class);\n    EverythingWithDefaults actual = newEverythingWithDefaults();\n\n    // Iterate over the annotation members to see if any differ. We could just compare expected and\n    // actual but if the comparison failed it could be hard to see exactly what differed.\n    StringBuilder differencesBuilder = new StringBuilder();\n    for (Method member : EverythingWithDefaults.class.getDeclaredMethods()) {\n      String name = member.getName();\n      Object expectedValue = member.invoke(expected);\n      Object actualValue = member.invoke(actual);\n      if (!equal(expectedValue, actualValue)) {\n        differencesBuilder\n            .append(\"For \")\n            .append(name)\n            .append(\" expected <\")\n            .append(string(expectedValue))\n            .append(\"> but was <\")\n            .append(string(actualValue))\n            .append(\">\\n\");\n      }\n    }\n    String differences = differencesBuilder.toString();\n    assertTrue(differences, differences.isEmpty());\n\n    // All the members were the same. Check that the equals and hashCode results say so too.\n    new EqualsTester().addEqualityGroup(expected, actual).testEquals();\n  }\n\n  private static boolean equal(Object x, Object y) {\n    return Arrays.deepEquals(new Object[] {x}, new Object[] {y});\n  }\n\n  private static String string(Object x) {\n    String s = Arrays.deepToString(new Object[] {x});\n    return s.substring(1, s.length() - 1);\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/AutoAnnotationTest.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.common.truth.TruthJUnit.assume;\n\nimport com.google.auto.value.annotations.Empty;\nimport com.google.auto.value.annotations.GwtArrays;\nimport com.google.auto.value.annotations.StringValues;\nimport com.google.common.base.StandardSystemProperty;\nimport com.google.common.collect.ImmutableCollection;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.ImmutableSortedSet;\nimport com.google.common.testing.EqualsTester;\nimport com.google.common.testing.SerializableTester;\nimport java.io.ObjectStreamClass;\nimport java.lang.annotation.Annotation;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.LinkedHashSet;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.SortedSet;\nimport java.util.TreeSet;\nimport org.junit.AssumptionViolatedException;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class AutoAnnotationTest {\n  @AutoAnnotation\n  private static StringValues newStringValues(String[] value) {\n    return new AutoAnnotation_AutoAnnotationTest_newStringValues(value);\n  }\n\n  @Empty\n  @StringValues(\"oops\")\n  static class AnnotatedClass {}\n\n  @Test\n  public void testSimple() {\n    StringValues expectedStringValues = AnnotatedClass.class.getAnnotation(StringValues.class);\n    StringValues actualStringValues = newStringValues(new String[] {\"oops\"});\n    StringValues otherStringValues = newStringValues(new String[] {});\n    new EqualsTester()\n        .addEqualityGroup(expectedStringValues, actualStringValues)\n        .addEqualityGroup(otherStringValues)\n        .testEquals();\n  }\n\n  @Test\n  public void testEqualsParameterAnnotation() throws ReflectiveOperationException {\n    assume()\n        .that(Double.parseDouble(StandardSystemProperty.JAVA_SPECIFICATION_VERSION.value()))\n        .isAtLeast(8.0);\n    Class<? extends Annotation> jspecifyNullable;\n    try {\n      // We write this using .concat in order to hide it from rewriting rules.\n      jspecifyNullable =\n          Class.forName(\"org\".concat(\".jspecify.annotations.Nullable\"))\n              .asSubclass(Annotation.class);\n    } catch (ClassNotFoundException e) {\n      throw new AssumptionViolatedException(\"No JSpecify @Nullable available\", e);\n    }\n    @SuppressWarnings(\"GetClassOnAnnotation\") // yes, I really want the implementation class\n    Class<? extends StringValues> autoAnnotationImpl = newStringValues(new String[0]).getClass();\n    Method equals = autoAnnotationImpl.getDeclaredMethod(\"equals\", Object.class);\n    assertThat(equals.getAnnotatedParameterTypes()[0].isAnnotationPresent(jspecifyNullable))\n        .isTrue();\n  }\n\n  @Test\n  public void testArraysAreCloned() {\n    String[] array = {\"Jekyll\"};\n    StringValues stringValues = newStringValues(array);\n    array[0] = \"Hyde\";\n    assertThat(stringValues.value()).asList().containsExactly(\"Jekyll\");\n    stringValues.value()[0] = \"Hyde\";\n    assertThat(stringValues.value()[0]).isEqualTo(\"Jekyll\");\n  }\n\n  @Test\n  public void testGwtArraysAreCloned() {\n    String[] strings = {\"Jekyll\"};\n    int[] ints = {2, 3, 5};\n    GwtArrays arrays = newGwtArrays(strings, ints);\n    assertThat(arrays.strings()).asList().containsExactly(\"Jekyll\");\n    assertThat(arrays.ints()).asList().containsExactly(2, 3, 5).inOrder();\n    strings[0] = \"Hyde\";\n    ints[0] = -1;\n    assertThat(arrays.strings()).asList().containsExactly(\"Jekyll\");\n    assertThat(arrays.ints()).asList().containsExactly(2, 3, 5).inOrder();\n  }\n\n  @AutoAnnotation\n  private static GwtArrays newGwtArrays(String[] strings, int[] ints) {\n    return new AutoAnnotation_AutoAnnotationTest_newGwtArrays(strings, ints);\n  }\n\n  @AutoAnnotation\n  private static StringValues newStringValuesVarArgs(String... value) {\n    return new AutoAnnotation_AutoAnnotationTest_newStringValuesVarArgs(value);\n  }\n\n  @Test\n  public void testSimpleVarArgs() {\n    StringValues expectedStringValues = AnnotatedClass.class.getAnnotation(StringValues.class);\n    StringValues actualStringValues = newStringValuesVarArgs(\"oops\");\n    StringValues otherStringValues = newStringValuesVarArgs(new String[] {});\n    new EqualsTester()\n        .addEqualityGroup(expectedStringValues, actualStringValues)\n        .addEqualityGroup(otherStringValues)\n        .testEquals();\n  }\n\n  @AutoAnnotation\n  private static Empty newEmpty() {\n    return new AutoAnnotation_AutoAnnotationTest_newEmpty();\n  }\n\n  @Test\n  public void testEmpty() {\n    Empty expectedEmpty = AnnotatedClass.class.getAnnotation(Empty.class);\n    Empty actualEmpty = newEmpty();\n    new EqualsTester().addEqualityGroup(expectedEmpty, actualEmpty).testEquals();\n  }\n\n  @Retention(RetentionPolicy.RUNTIME)\n  @interface Everything {\n    byte aByte();\n\n    short aShort();\n\n    int anInt();\n\n    long aLong();\n\n    float aFloat();\n\n    double aDouble();\n\n    char aChar();\n\n    boolean aBoolean();\n\n    String aString();\n\n    RetentionPolicy anEnum();\n\n    StringValues anAnnotation();\n\n    Class<? extends CharSequence> aClass();\n\n    byte[] bytes();\n\n    short[] shorts();\n\n    int[] ints();\n\n    long[] longs();\n\n    float[] floats();\n\n    double[] doubles();\n\n    char[] chars();\n\n    boolean[] booleans();\n\n    String[] strings();\n\n    RetentionPolicy[] enums();\n\n    StringValues[] annotations();\n\n    Class<? extends CharSequence>[] classes();\n  }\n\n  @AutoAnnotation\n  static Everything newEverything(\n      byte aByte,\n      short aShort,\n      int anInt,\n      long aLong,\n      float aFloat,\n      double aDouble,\n      char aChar,\n      boolean aBoolean,\n      String aString,\n      RetentionPolicy anEnum,\n      StringValues anAnnotation,\n      Class<? extends CharSequence> aClass,\n      byte[] bytes,\n      short[] shorts,\n      int[] ints,\n      long[] longs,\n      float[] floats,\n      double[] doubles,\n      char[] chars,\n      boolean[] booleans,\n      String[] strings,\n      RetentionPolicy[] enums,\n      StringValues[] annotations,\n      Class<? extends CharSequence>... classes) {\n    return new AutoAnnotation_AutoAnnotationTest_newEverything(\n        aByte,\n        aShort,\n        anInt,\n        aLong,\n        aFloat,\n        aDouble,\n        aChar,\n        aBoolean,\n        aString,\n        anEnum,\n        anAnnotation,\n        aClass,\n        bytes,\n        shorts,\n        ints,\n        longs,\n        floats,\n        doubles,\n        chars,\n        booleans,\n        strings,\n        enums,\n        annotations,\n        classes);\n  }\n\n  @AutoAnnotation\n  static Everything newEverythingCollections(\n      byte aByte,\n      short aShort,\n      int anInt,\n      long aLong,\n      float aFloat,\n      double aDouble,\n      char aChar,\n      boolean aBoolean,\n      String aString,\n      RetentionPolicy anEnum,\n      StringValues anAnnotation,\n      Class<? extends CharSequence> aClass,\n      Collection<Byte> bytes,\n      List<Short> shorts,\n      ArrayList<Integer> ints,\n      Set<Long> longs,\n      SortedSet<Float> floats,\n      TreeSet<Double> doubles,\n      LinkedHashSet<Character> chars,\n      ImmutableCollection<Boolean> booleans,\n      ImmutableList<String> strings,\n      ImmutableSet<RetentionPolicy> enums,\n      Set<StringValues> annotations,\n      List<Class<? extends CharSequence>> classes) {\n    return new AutoAnnotation_AutoAnnotationTest_newEverythingCollections(\n        aByte,\n        aShort,\n        anInt,\n        aLong,\n        aFloat,\n        aDouble,\n        aChar,\n        aBoolean,\n        aString,\n        anEnum,\n        anAnnotation,\n        aClass,\n        bytes,\n        shorts,\n        ints,\n        longs,\n        floats,\n        doubles,\n        chars,\n        booleans,\n        strings,\n        enums,\n        annotations,\n        classes);\n  }\n\n  @Everything(\n      aByte = 1,\n      aShort = 2,\n      anInt = 3,\n      aLong = -4,\n      aFloat = Float.NaN,\n      aDouble = Double.NaN,\n      aChar = '#',\n      aBoolean = true,\n      aString = \"maybe\\nmaybe not\\n\",\n      anEnum = RetentionPolicy.RUNTIME,\n      anAnnotation = @StringValues(\"whatever\"),\n      aClass = String.class,\n      bytes = {5, 6},\n      shorts = {},\n      ints = {7},\n      longs = {8, 9},\n      floats = {10, 11},\n      doubles = {Double.NEGATIVE_INFINITY, -12.0, Double.POSITIVE_INFINITY},\n      chars = {'?', '!', '\\n'},\n      booleans = {false, true, false},\n      strings = {\"ver\", \"vers\", \"vert\", \"verre\", \"vair\"},\n      enums = {RetentionPolicy.CLASS, RetentionPolicy.RUNTIME},\n      annotations = {@StringValues({}), @StringValues({\"foo\", \"bar\"})},\n      classes = {String.class, StringBuilder.class})\n  private static class AnnotatedWithEverything {}\n\n  // Get an instance of @Everything via reflection on the class AnnotatedWithEverything,\n  // fabricate an instance using newEverything that is supposed to be equal to it, and\n  // fabricate another instance using newEverything that is supposed to be different.\n  private static final Everything EVERYTHING_FROM_REFLECTION =\n      AnnotatedWithEverything.class.getAnnotation(Everything.class);\n  private static final Everything EVERYTHING_FROM_AUTO =\n      newEverything(\n          (byte) 1,\n          (short) 2,\n          3,\n          -4,\n          Float.NaN,\n          Double.NaN,\n          '#',\n          true,\n          \"maybe\\nmaybe not\\n\",\n          RetentionPolicy.RUNTIME,\n          newStringValues(new String[] {\"whatever\"}),\n          String.class,\n          new byte[] {5, 6},\n          new short[] {},\n          new int[] {7},\n          new long[] {8, 9},\n          new float[] {10, 11},\n          new double[] {Double.NEGATIVE_INFINITY, -12.0, Double.POSITIVE_INFINITY},\n          new char[] {'?', '!', '\\n'},\n          new boolean[] {false, true, false},\n          new String[] {\"ver\", \"vers\", \"vert\", \"verre\", \"vair\"},\n          new RetentionPolicy[] {RetentionPolicy.CLASS, RetentionPolicy.RUNTIME},\n          new StringValues[] {\n            newStringValues(new String[] {}), newStringValues(new String[] {\"foo\", \"bar\"}),\n          },\n          String.class,\n          StringBuilder.class);\n  private static final Everything EVERYTHING_FROM_AUTO_COLLECTIONS =\n      newEverythingCollections(\n          (byte) 1,\n          (short) 2,\n          3,\n          -4,\n          Float.NaN,\n          Double.NaN,\n          '#',\n          true,\n          \"maybe\\nmaybe not\\n\",\n          RetentionPolicy.RUNTIME,\n          newStringValues(new String[] {\"whatever\"}),\n          String.class,\n          Arrays.asList((byte) 5, (byte) 6),\n          Collections.<Short>emptyList(),\n          new ArrayList<Integer>(Collections.singleton(7)),\n          ImmutableSet.of(8L, 9L),\n          ImmutableSortedSet.of(10f, 11f),\n          new TreeSet<Double>(\n              ImmutableList.of(Double.NEGATIVE_INFINITY, -12.0, Double.POSITIVE_INFINITY)),\n          new LinkedHashSet<Character>(ImmutableList.of('?', '!', '\\n')),\n          ImmutableList.of(false, true, false),\n          ImmutableList.of(\"ver\", \"vers\", \"vert\", \"verre\", \"vair\"),\n          ImmutableSet.of(RetentionPolicy.CLASS, RetentionPolicy.RUNTIME),\n          ImmutableSet.of(\n              newStringValues(new String[] {}), newStringValues(new String[] {\"foo\", \"bar\"})),\n          ImmutableList.of(String.class.asSubclass(CharSequence.class), StringBuilder.class));\n  // .asSubclass because of pre-Java8, where otherwise we get a compilation error because\n  // the inferred type is <Class<? extends CharSequence & Serializable>>.\n  private static final Everything EVERYTHING_ELSE_FROM_AUTO =\n      newEverything(\n          (byte) 0,\n          (short) 0,\n          0,\n          0,\n          0,\n          0,\n          '0',\n          false,\n          \"\",\n          RetentionPolicy.SOURCE,\n          newStringValues(new String[] {\"\"}),\n          String.class,\n          new byte[0],\n          new short[0],\n          new int[0],\n          new long[0],\n          new float[0],\n          new double[0],\n          new char[0],\n          new boolean[0],\n          new String[0],\n          new RetentionPolicy[0],\n          new StringValues[0]);\n  private static final Everything EVERYTHING_ELSE_FROM_AUTO_COLLECTIONS =\n      newEverythingCollections(\n          (byte) 0,\n          (short) 0,\n          0,\n          0,\n          0,\n          0,\n          '0',\n          false,\n          \"\",\n          RetentionPolicy.SOURCE,\n          newStringValues(new String[] {\"\"}),\n          String.class,\n          ImmutableList.<Byte>of(),\n          Collections.<Short>emptyList(),\n          new ArrayList<Integer>(),\n          Collections.<Long>emptySet(),\n          ImmutableSortedSet.<Float>of(),\n          new TreeSet<Double>(),\n          new LinkedHashSet<Character>(),\n          ImmutableSet.<Boolean>of(),\n          ImmutableList.<String>of(),\n          ImmutableSet.<RetentionPolicy>of(),\n          Collections.<StringValues>emptySet(),\n          Collections.<Class<? extends CharSequence>>emptyList());\n\n  @Test\n  public void testEqualsAndHashCode() {\n    new EqualsTester()\n        .addEqualityGroup(\n            EVERYTHING_FROM_REFLECTION, EVERYTHING_FROM_AUTO, EVERYTHING_FROM_AUTO_COLLECTIONS)\n        .addEqualityGroup(EVERYTHING_ELSE_FROM_AUTO, EVERYTHING_ELSE_FROM_AUTO_COLLECTIONS)\n        .testEquals();\n  }\n\n  @Test\n  public void testSerialization() {\n    Annotation[] instances = {EVERYTHING_FROM_AUTO, EVERYTHING_FROM_AUTO_COLLECTIONS};\n    for (Annotation instance : instances) {\n      SerializableTester.reserializeAndAssert(instance);\n    }\n  }\n\n  @Test\n  @SuppressWarnings(\"GetClassOnAnnotation\") // yes, we really do want the implementation classes\n  public void testSerialVersionUid() {\n    Class<? extends Everything> everythingImpl = EVERYTHING_FROM_AUTO.getClass();\n    Class<? extends Everything> everythingFromCollectionsImpl =\n        EVERYTHING_FROM_AUTO_COLLECTIONS.getClass();\n    assertThat(everythingImpl).isNotEqualTo(everythingFromCollectionsImpl);\n    long everythingUid = ObjectStreamClass.lookup(everythingImpl).getSerialVersionUID();\n    long everythingFromCollectionsUid =\n        ObjectStreamClass.lookup(everythingFromCollectionsImpl).getSerialVersionUID();\n    // Two different implementations of the same annotation with the same members being provided\n    // (not defaulted) should have the same serialVersionUID. They won't be serial-compatible, of\n    // course, because their classes are different. So we're really just checking that the\n    // serialVersionUID depends only on the names and types of those members.\n    assertThat(everythingFromCollectionsUid).isEqualTo(everythingUid);\n    Class<? extends StringValues> stringValuesImpl = newStringValues(new String[0]).getClass();\n    long stringValuesUid = ObjectStreamClass.lookup(stringValuesImpl).getSerialVersionUID();\n    // The previous assertion would be vacuously true if every implementation had the same\n    // serialVersionUID, so check that that's not true.\n    assertThat(stringValuesUid).isNotEqualTo(everythingUid);\n  }\n\n  public static class IntList extends ArrayList<Integer> {\n    private static final long serialVersionUID = 1L;\n\n    IntList(Collection<Integer> c) {\n      super(c);\n    }\n  }\n\n  @Retention(RetentionPolicy.RUNTIME)\n  @interface IntArray {\n    int[] ints();\n  }\n\n  @IntArray(ints = {1, 2, 3})\n  private static class AnnotatedWithIntArray {}\n\n  @AutoAnnotation\n  static IntArray newIntArray(IntList ints) {\n    return new AutoAnnotation_AutoAnnotationTest_newIntArray(ints);\n  }\n\n  /**\n   * Test that we can represent a primitive array member with a parameter whose type is a collection\n   * of the corresponding wrapper type, even if the wrapper type is not explicitly a type parameter.\n   * Specifically, if the member is an {@code int[]} then obviously we can represent it as a {@code\n   * List<Integer>}, but here we test that we can also represent it as an {@code IntList}, which is\n   * only a {@code List<Integer>} by virtue of inheritance. This is a separate test rather than just\n   * putting an {@code IntList} parameter into {@link #newEverythingCollections} because we want to\n   * check that we are still able to detect the primitive wrapper type even though it's hidden in\n   * this way. We need to generate a helper method for every primitive wrapper.\n   */\n  @Test\n  public void testDerivedPrimitiveCollection() {\n    IntList intList = new IntList(ImmutableList.of(1, 2, 3));\n    IntArray actual = newIntArray(intList);\n    IntArray expected = AnnotatedWithIntArray.class.getAnnotation(IntArray.class);\n    assertThat(actual).isEqualTo(expected);\n  }\n\n  @Test\n  public void testToString() {\n    String expected =\n        \"@com.google.auto.value.AutoAnnotationTest.Everything(\"\n            + \"aByte=1, aShort=2, anInt=3, aLong=-4, aFloat=NaN, aDouble=NaN, aChar='#', \"\n            + \"aBoolean=true, aString=\\\"maybe\\\\nmaybe not\\\\n\\\", anEnum=RUNTIME, \"\n            + \"anAnnotation=@com.google.auto.value.annotations.StringValues([\\\"whatever\\\"]), \"\n            + \"aClass=class java.lang.String, \"\n            + \"bytes=[5, 6], shorts=[], ints=[7], longs=[8, 9], floats=[10.0, 11.0], \"\n            + \"doubles=[-Infinity, -12.0, Infinity], \"\n            + \"chars=['?', '!', '\\\\n'], \"\n            + \"booleans=[false, true, false], \"\n            + \"strings=[\\\"ver\\\", \\\"vers\\\", \\\"vert\\\", \\\"verre\\\", \\\"vair\\\"], \"\n            + \"enums=[CLASS, RUNTIME], \"\n            + \"annotations=[\"\n            + \"@com.google.auto.value.annotations.StringValues([]), \"\n            + \"@com.google.auto.value.annotations.StringValues([\\\"foo\\\", \\\"bar\\\"])\"\n            + \"], \"\n            + \"classes=[class java.lang.String, class java.lang.StringBuilder]\"\n            + \")\";\n    assertThat(EVERYTHING_FROM_AUTO.toString()).isEqualTo(expected);\n    assertThat(EVERYTHING_FROM_AUTO_COLLECTIONS.toString()).isEqualTo(expected);\n  }\n\n  @Test\n  public void testStringQuoting() {\n    StringValues instance =\n        newStringValues(\n            new String[] {\n              \"\", \"\\r\\n\", \"hello, world\", \"Éamonn\", \"\\007\\uffef\",\n            });\n    String expected =\n        \"@com.google.auto.value.annotations.StringValues(\"\n            + \"[\\\"\\\", \\\"\\\\r\\\\n\\\", \\\"hello, world\\\", \\\"Éamonn\\\", \\\"\\\\007\\\\uffef\\\"])\";\n    assertThat(instance.toString()).isEqualTo(expected);\n  }\n\n  @Retention(RetentionPolicy.RUNTIME)\n  @interface AnnotationsAnnotation {\n    Class<? extends Annotation>[] value();\n  }\n\n  @AnnotationsAnnotation(AnnotationsAnnotation.class)\n  static class AnnotatedWithAnnotationsAnnotation {}\n\n  @AutoAnnotation\n  static AnnotationsAnnotation newAnnotationsAnnotation(List<Class<? extends Annotation>> value) {\n    return new AutoAnnotation_AutoAnnotationTest_newAnnotationsAnnotation(value);\n  }\n\n  @Test\n  public void testGenericArray() {\n    AnnotationsAnnotation generated =\n        newAnnotationsAnnotation(\n            ImmutableList.<Class<? extends Annotation>>of(AnnotationsAnnotation.class));\n    AnnotationsAnnotation fromReflect =\n        AnnotatedWithAnnotationsAnnotation.class.getAnnotation(AnnotationsAnnotation.class);\n    assertThat(generated).isEqualTo(fromReflect);\n  }\n\n  @Retention(RetentionPolicy.RUNTIME)\n  @interface ClassesAnnotation {\n    Class<?>[] value();\n  }\n\n  @ClassesAnnotation(AnnotationsAnnotation.class)\n  static class AnnotatedWithClassesAnnotation {}\n\n  @AutoAnnotation\n  static ClassesAnnotation newClassesAnnotation(List<Class<?>> value) {\n    return new AutoAnnotation_AutoAnnotationTest_newClassesAnnotation(value);\n  }\n\n  @Test\n  public void testWildcardArray() {\n    ClassesAnnotation generated =\n        newClassesAnnotation(Arrays.<Class<?>>asList(AnnotationsAnnotation.class));\n    ClassesAnnotation fromReflect =\n        AnnotatedWithClassesAnnotation.class.getAnnotation(ClassesAnnotation.class);\n    assertThat(generated).isEqualTo(fromReflect);\n  }\n\n  @Retention(RetentionPolicy.RUNTIME)\n  @interface IntegersAnnotation {\n    int one() default Integer.MAX_VALUE;\n\n    int two() default Integer.MAX_VALUE;\n\n    int three();\n  }\n\n  @IntegersAnnotation(three = 23)\n  static class AnnotatedWithIntegersAnnotation {}\n\n  @AutoAnnotation\n  static IntegersAnnotation newIntegersAnnotation(int three) {\n    return new AutoAnnotation_AutoAnnotationTest_newIntegersAnnotation(three);\n  }\n\n  @Test\n  public void testConstantOverflowInHashCode() {\n    IntegersAnnotation generated = newIntegersAnnotation(23);\n    IntegersAnnotation fromReflect =\n        AnnotatedWithIntegersAnnotation.class.getAnnotation(IntegersAnnotation.class);\n    new EqualsTester().addEqualityGroup(generated, fromReflect).testEquals();\n  }\n\n  @Retention(RetentionPolicy.RUNTIME)\n  @interface EverythingWithDefaults {\n    byte aByte() default 5;\n\n    short aShort() default 17;\n\n    int anInt() default 23;\n\n    long aLong() default 1729;\n\n    float aFloat() default 5;\n\n    double aDouble() default 17;\n\n    char aChar() default 'x';\n\n    boolean aBoolean() default true;\n\n    String aString() default \"whatever\";\n\n    RetentionPolicy anEnum() default RetentionPolicy.CLASS;\n\n    // We don't yet support defaulting annotation values.\n    // StringValues anAnnotation() default @StringValues({\"foo\", \"bar\"});\n    byte[] bytes() default {1, 2};\n\n    short[] shorts() default {3, 4};\n\n    int[] ints() default {5, 6};\n\n    long[] longs() default {7, 8};\n\n    float[] floats() default {9, 10};\n\n    double[] doubles() default {11, 12};\n\n    char[] chars() default {'D', 'E'};\n\n    boolean[] booleans() default {true, false};\n\n    String[] strings() default {\"vrai\", \"faux\"};\n\n    RetentionPolicy[] enums() default {RetentionPolicy.SOURCE, RetentionPolicy.CLASS};\n    // We don't yet support defaulting annotation values.\n    // StringValues[] annotations() default {\n    //   @StringValues({\"foo\", \"bar\"}), @StringValues({\"baz\", \"buh\"})\n    // };\n  }\n\n  @EverythingWithDefaults\n  static class AnnotatedWithEverythingWithDefaults {}\n\n  @AutoAnnotation\n  static EverythingWithDefaults newEverythingWithDefaults() {\n    return new AutoAnnotation_AutoAnnotationTest_newEverythingWithDefaults();\n  }\n\n  @Test\n  public void testDefaultedValues() {\n    EverythingWithDefaults generated = newEverythingWithDefaults();\n    EverythingWithDefaults fromReflect =\n        AnnotatedWithEverythingWithDefaults.class.getAnnotation(EverythingWithDefaults.class);\n    new EqualsTester().addEqualityGroup(generated, fromReflect).testEquals();\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/AutoBuilderKotlinTest.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.assertThrows;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport java.util.List;\nimport java.util.Map;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic final class AutoBuilderKotlinTest {\n  @AutoBuilder(ofClass = KotlinData.class)\n  abstract static class KotlinDataBuilder {\n    static KotlinDataBuilder builder() {\n      return new AutoBuilder_AutoBuilderKotlinTest_KotlinDataBuilder();\n    }\n\n    static KotlinDataBuilder builder(KotlinData kotlinData) {\n      return new AutoBuilder_AutoBuilderKotlinTest_KotlinDataBuilder(kotlinData);\n    }\n\n    abstract KotlinDataBuilder setInt(int x);\n\n    abstract KotlinDataBuilder setString(String x);\n\n    abstract KotlinData build();\n  }\n\n  @Test\n  public void simpleKotlin() {\n    KotlinData x = KotlinDataBuilder.builder().setInt(23).setString(\"skidoo\").build();\n    assertThat(x.getInt()).isEqualTo(23);\n    assertThat(x.getString()).isEqualTo(\"skidoo\");\n\n    KotlinData y = KotlinDataBuilder.builder(x).setString(\"chromosomes\").build();\n    assertThat(y.getInt()).isEqualTo(23);\n    assertThat(y.getString()).isEqualTo(\"chromosomes\");\n\n    assertThrows(IllegalStateException.class, () -> KotlinDataBuilder.builder().build());\n  }\n\n  @AutoBuilder(ofClass = KotlinDataWithNullable.class)\n  abstract static class KotlinDataWithNullableBuilder {\n    static KotlinDataWithNullableBuilder builder() {\n      return new AutoBuilder_AutoBuilderKotlinTest_KotlinDataWithNullableBuilder();\n    }\n\n    abstract KotlinDataWithNullableBuilder setAnInt(int x);\n\n    abstract KotlinDataWithNullableBuilder setAString(String x);\n\n    abstract KotlinDataWithNullable build();\n  }\n\n  @Test\n  public void kotlinWithNullable() {\n    KotlinDataWithNullable empty = KotlinDataWithNullableBuilder.builder().build();\n    assertThat(empty.getAnInt()).isNull();\n    assertThat(empty.getAString()).isNull();\n\n    KotlinDataWithNullable notEmpty =\n        KotlinDataWithNullableBuilder.builder().setAString(\"answer\").setAnInt(42).build();\n    assertThat(notEmpty.getAString()).isEqualTo(\"answer\");\n    assertThat(notEmpty.getAnInt()).isEqualTo(42);\n  }\n\n  @AutoBuilder(ofClass = KotlinDataWithDefaults.class)\n  abstract static class KotlinDataWithDefaultsBuilder {\n    static KotlinDataWithDefaultsBuilder builder() {\n      return new AutoBuilder_AutoBuilderKotlinTest_KotlinDataWithDefaultsBuilder();\n    }\n\n    abstract KotlinDataWithDefaultsBuilder setAnInt(int x);\n\n    abstract int getAnInt();\n\n    abstract ImmutableList.Builder<String> anImmutableListBuilder();\n\n    abstract KotlinDataWithDefaultsBuilder setNotDefaulted(long x);\n\n    abstract long getNotDefaulted();\n\n    abstract KotlinDataWithDefaultsBuilder setAString(String x);\n\n    abstract String getAString();\n\n    abstract KotlinDataWithDefaults build();\n  }\n\n  @Test\n  public void kotlinWithDefaults_explicit() {\n    KotlinDataWithDefaultsBuilder builder =\n        KotlinDataWithDefaultsBuilder.builder()\n            .setAString(\"answer\")\n            .setNotDefaulted(100L)\n            .setAnInt(42);\n    builder.anImmutableListBuilder().add(\"bar\");\n    KotlinDataWithDefaults x = builder.build();\n    assertThat(x.getAString()).isEqualTo(\"answer\");\n    assertThat(x.getAnImmutableList()).containsExactly(\"bar\");\n    assertThat(x.getNotDefaulted()).isEqualTo(100L);\n    assertThat(x.getAnInt()).isEqualTo(42);\n  }\n\n  @Test\n  public void kotlinWithDefaults_defaulted() {\n    KotlinDataWithDefaults x =\n        KotlinDataWithDefaultsBuilder.builder().setNotDefaulted(100L).build();\n    assertThat(x.getAnInt()).isEqualTo(23);\n    assertThat(x.getAnImmutableList()).containsExactly(\"foo\");\n    assertThat(x.getAString()).isEqualTo(\"skidoo\");\n    assertThat(x.getNotDefaulted()).isEqualTo(100L);\n    KotlinDataWithDefaults copy =\n        new AutoBuilder_AutoBuilderKotlinTest_KotlinDataWithDefaultsBuilder(x).build();\n    assertThat(copy).isEqualTo(x);\n    assertThat(copy).isNotSameInstanceAs(x);\n    KotlinDataWithDefaults modified =\n        new AutoBuilder_AutoBuilderKotlinTest_KotlinDataWithDefaultsBuilder(x).setAnInt(17).build();\n    assertThat(modified.getAnInt()).isEqualTo(17);\n  }\n\n  @Test\n  public void kotlinWithDefaults_getter() {\n    KotlinDataWithDefaultsBuilder builder = KotlinDataWithDefaultsBuilder.builder();\n    assertThrows(IllegalStateException.class, builder::getAnInt);\n    builder.setAnInt(42);\n    assertThat(builder.getAnInt()).isEqualTo(42);\n    assertThrows(IllegalStateException.class, builder::getNotDefaulted);\n    builder.setNotDefaulted(100L);\n    assertThat(builder.getNotDefaulted()).isEqualTo(100L);\n    assertThrows(IllegalStateException.class, builder::getAString);\n    builder.setAString(\"answer\");\n    assertThat(builder.getAString()).isEqualTo(\"answer\");\n  }\n\n  @AutoBuilder(ofClass = KotlinDataEightDefaults.class)\n  interface KotlinDataEightDefaultsBuilder {\n    static KotlinDataEightDefaultsBuilder builder() {\n      return new AutoBuilder_AutoBuilderKotlinTest_KotlinDataEightDefaultsBuilder();\n    }\n\n    KotlinDataEightDefaultsBuilder a1(int x);\n\n    KotlinDataEightDefaultsBuilder a2(int x);\n\n    KotlinDataEightDefaultsBuilder a3(int x);\n\n    KotlinDataEightDefaultsBuilder a4(int x);\n\n    KotlinDataEightDefaultsBuilder a5(int x);\n\n    KotlinDataEightDefaultsBuilder a6(int x);\n\n    KotlinDataEightDefaultsBuilder a7(int x);\n\n    KotlinDataEightDefaultsBuilder a8(int x);\n\n    KotlinDataEightDefaults build();\n  }\n\n  // We test a class that has exactly 8 default parameters because we will use a byte for the\n  // bitmask in that case and it is possible that we might have an issue with sign extension when\n  // bit 7 of that bitmask is set.\n  @Test\n  public void kotlinEightDefaults() {\n    KotlinDataEightDefaults allDefaulted = KotlinDataEightDefaultsBuilder.builder().build();\n    assertThat(allDefaulted.getA1()).isEqualTo(1);\n    assertThat(allDefaulted.getA8()).isEqualTo(8);\n    KotlinDataEightDefaults noneDefaulted =\n        KotlinDataEightDefaultsBuilder.builder()\n            .a1(-1)\n            .a2(-2)\n            .a3(-3)\n            .a4(-4)\n            .a5(-5)\n            .a6(-6)\n            .a7(-7)\n            .a8(-8)\n            .build();\n    assertThat(noneDefaulted.getA1()).isEqualTo(-1);\n    assertThat(noneDefaulted.getA8()).isEqualTo(-8);\n  }\n\n  @AutoBuilder(ofClass = KotlinDataSomeDefaults.class)\n  interface KotlinDataSomeDefaultsBuilder {\n    static KotlinDataSomeDefaultsBuilder builder() {\n      return new AutoBuilder_AutoBuilderKotlinTest_KotlinDataSomeDefaultsBuilder();\n    }\n\n    static KotlinDataSomeDefaultsBuilder fromInstance(KotlinDataSomeDefaults instance) {\n      return new AutoBuilder_AutoBuilderKotlinTest_KotlinDataSomeDefaultsBuilder(instance);\n    }\n\n    KotlinDataSomeDefaultsBuilder requiredInt(int x);\n\n    KotlinDataSomeDefaultsBuilder requiredString(String x);\n\n    KotlinDataSomeDefaultsBuilder optionalInt(int x);\n\n    KotlinDataSomeDefaultsBuilder optionalString(String x);\n\n    KotlinDataSomeDefaults build();\n  }\n\n  @Test\n  public void kotlinSomeDefaults_someDefaulted() {\n    KotlinDataSomeDefaults someDefaulted =\n        KotlinDataSomeDefaultsBuilder.builder().requiredInt(12).requiredString(\"Monkeys\").build();\n    assertThat(someDefaulted.getOptionalInt()).isEqualTo(23);\n    assertThat(someDefaulted.getOptionalString()).isEqualTo(\"Skidoo\");\n    assertThat(KotlinDataSomeDefaultsBuilder.fromInstance(someDefaulted).build())\n        .isEqualTo(someDefaulted);\n  }\n\n  @Test\n  public void kotlinSomeDefaults_noneDefaulted() {\n    KotlinDataSomeDefaults noneDefaulted =\n        KotlinDataSomeDefaultsBuilder.builder()\n            .requiredInt(12)\n            .requiredString(\"Monkeys\")\n            .optionalInt(3)\n            .optionalString(\"Oranges\")\n            .build();\n    KotlinDataSomeDefaults copy = KotlinDataSomeDefaultsBuilder.fromInstance(noneDefaulted).build();\n    assertThat(copy).isEqualTo(noneDefaulted);\n  }\n\n  @Test\n  public void kotlinSomeDefaults_missingRequired() {\n    IllegalStateException e =\n        assertThrows(\n            IllegalStateException.class, () -> KotlinDataSomeDefaultsBuilder.builder().build());\n    assertThat(e).hasMessageThat().contains(\"requiredInt\");\n    assertThat(e).hasMessageThat().contains(\"requiredString\");\n  }\n\n  @AutoBuilder(ofClass = KotlinDataSomeDefaultsBig.class)\n  interface KotlinDataSomeDefaultsBigBuilder {\n    static KotlinDataSomeDefaultsBigBuilder builder() {\n      return new AutoBuilder_AutoBuilderKotlinTest_KotlinDataSomeDefaultsBigBuilder();\n    }\n\n    KotlinDataSomeDefaultsBigBuilder requiredInt(int x);\n\n    KotlinDataSomeDefaultsBigBuilder requiredString(String x);\n\n    KotlinDataSomeDefaultsBigBuilder a1(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a2(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a3(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a4(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a5(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a6(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a7(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a8(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a9(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a10(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a11(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a12(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a13(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a14(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a15(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a16(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a17(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a18(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a19(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a20(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a21(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a22(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a23(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a24(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a25(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a26(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a27(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a28(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a29(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a30(int x);\n\n    KotlinDataSomeDefaultsBigBuilder a31(int x);\n\n    KotlinDataSomeDefaultsBig build();\n  }\n\n  @Test\n  public void kotlinSomeDefaultsBig() {\n    KotlinDataSomeDefaultsBig allDefaulted =\n        KotlinDataSomeDefaultsBigBuilder.builder().requiredInt(23).requiredString(\"skidoo\").build();\n    assertThat(allDefaulted.getRequiredInt()).isEqualTo(23);\n    assertThat(allDefaulted.getRequiredString()).isEqualTo(\"skidoo\");\n    assertThat(allDefaulted.getA1()).isEqualTo(1);\n    assertThat(allDefaulted.getA31()).isEqualTo(31);\n  }\n\n  @AutoBuilder(ofClass = KotlinDataWithList.class)\n  interface KotlinDataWithListBuilder {\n    static KotlinDataWithListBuilder builder() {\n      return new AutoBuilder_AutoBuilderKotlinTest_KotlinDataWithListBuilder();\n    }\n\n    static KotlinDataWithListBuilder builder(KotlinDataWithList kotlinData) {\n      return new AutoBuilder_AutoBuilderKotlinTest_KotlinDataWithListBuilder(kotlinData);\n    }\n\n    KotlinDataWithListBuilder list(List<? extends CharSequence> list);\n\n    KotlinDataWithListBuilder number(int number);\n\n    KotlinDataWithList build();\n  }\n\n  // The `getList()` method returns `List<CharSequence>` as seen from Java, but the `list` parameter\n  // to the constructor has type `List<? extends CharSequence>`.\n  @Test\n  public void kotlinWildcards() {\n    List<String> strings = ImmutableList.of(\"foo\");\n    KotlinDataWithList x = KotlinDataWithListBuilder.builder().list(strings).number(17).build();\n    assertThat(x.getList()).isEqualTo(strings);\n    assertThat(x.getNumber()).isEqualTo(17);\n    KotlinDataWithList y = KotlinDataWithListBuilder.builder(x).number(23).build();\n    assertThat(y.getList()).isEqualTo(strings);\n    assertThat(y.getNumber()).isEqualTo(23);\n  }\n\n  @AutoBuilder(ofClass = KotlinDataWithTypeParameters.class)\n  interface KotlinDataWithTypeParametersBuilder<\n      T, U extends Number, V extends Number, W extends Number, M extends Map<String, ?>> {\n    static <T, U extends Number, V extends Number, W extends Number, M extends Map<String, ?>>\n        KotlinDataWithTypeParametersBuilder<T, U, V, W, M> builder() {\n      return new AutoBuilder_AutoBuilderKotlinTest_KotlinDataWithTypeParametersBuilder<\n          T, U, V, W, M>();\n    }\n\n    KotlinDataWithTypeParametersBuilder<T, U, V, W, M> t(T t);\n\n    KotlinDataWithTypeParametersBuilder<T, U, V, W, M> u(U u);\n\n    KotlinDataWithTypeParametersBuilder<T, U, V, W, M> v(V v);\n\n    KotlinDataWithTypeParametersBuilder<T, U, V, W, M> m(M m);\n\n    T getT();\n\n    U getU();\n\n    V getV();\n\n    M getM();\n\n    KotlinDataWithTypeParameters<T, U, V, W, M> build();\n  }\n\n  @Test\n  public void kotlinWithTypeParameters() {\n    KotlinDataWithTypeParametersBuilder<String, Integer, Double, Long, ImmutableMap<String, ?>>\n        builder = KotlinDataWithTypeParametersBuilder.builder();\n    ImmutableMap<String, Integer> map = ImmutableMap.of(\"hello\", 1);\n    KotlinDataWithTypeParameters<String, Integer, Double, Long, ImmutableMap<String, ?>> data =\n        builder.t(\"test\").u(1).v(2.0).m(map).build();\n    assertThat(data.getT()).isEqualTo(\"test\");\n    assertThat(data.getU()).isEqualTo(1);\n    assertThat(data.getV()).isEqualTo(2.0);\n    assertThat(data.getM()).isEqualTo(map);\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/AutoBuilderTest.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value;\n\nimport static com.google.common.base.Preconditions.checkNotNull;\nimport static com.google.common.truth.Truth.assertThat;\nimport static java.lang.annotation.ElementType.TYPE_USE;\nimport static java.util.stream.Collectors.joining;\nimport static org.junit.Assert.assertThrows;\nimport static org.junit.Assert.fail;\nimport static org.junit.Assume.assumeTrue;\n\nimport com.google.common.base.MoreObjects;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.truth.Truth;\nimport java.io.IOException;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\nimport java.math.BigInteger;\nimport java.time.LocalTime;\nimport java.util.AbstractSet;\nimport java.util.Collections;\nimport java.util.Iterator;\nimport java.util.Map;\nimport java.util.NoSuchElementException;\nimport java.util.Objects;\nimport java.util.Optional;\nimport java.util.Set;\nimport javax.lang.model.SourceVersion;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic final class AutoBuilderTest {\n  static class Simple {\n    private final int anInt;\n    private final String aString;\n\n    Simple(int anInt, String aString) {\n      this.anInt = anInt;\n      this.aString = aString;\n    }\n\n    static Simple of(int anInt, String aString) {\n      return new Simple(anInt, aString);\n    }\n\n    @Override\n    public boolean equals(Object x) {\n      if (x instanceof Simple) {\n        Simple that = (Simple) x;\n        return this.anInt == that.anInt && Objects.equals(this.aString, that.aString);\n      }\n      return false;\n    }\n\n    @Override\n    public int hashCode() {\n      return Objects.hash(anInt, aString);\n    }\n\n    @Override\n    public String toString() {\n      return MoreObjects.toStringHelper(this)\n          .add(\"anInt\", anInt)\n          .add(\"aString\", aString)\n          .toString();\n    }\n\n    static Builder builder() {\n      return new AutoBuilder_AutoBuilderTest_Simple_Builder();\n    }\n\n    @AutoBuilder\n    abstract static class Builder {\n      abstract Builder setAnInt(int x);\n\n      abstract Builder setAString(String x);\n\n      abstract Simple build();\n    }\n  }\n\n  @Test\n  public void simple() {\n    Simple x = Simple.builder().setAnInt(23).setAString(\"skidoo\").build();\n    assertThat(x).isEqualTo(new Simple(23, \"skidoo\"));\n  }\n\n  @AutoValue\n  abstract static class SimpleAuto {\n    abstract int getFoo();\n\n    abstract String getBar();\n\n    static Builder builder() {\n      return new AutoBuilder_AutoBuilderTest_SimpleAuto_Builder();\n    }\n\n    // There's no particular reason to do this since @AutoValue.Builder works just as well, but\n    // let's check anyway.\n    @AutoBuilder(ofClass = AutoValue_AutoBuilderTest_SimpleAuto.class)\n    abstract static class Builder {\n      abstract Builder setFoo(int x);\n\n      abstract Builder setBar(String x);\n\n      abstract AutoValue_AutoBuilderTest_SimpleAuto build();\n    }\n  }\n\n  @Test\n  public void simpleAuto() {\n    SimpleAuto x = SimpleAuto.builder().setFoo(23).setBar(\"skidoo\").build();\n    assertThat(x.getFoo()).isEqualTo(23);\n    assertThat(x.getBar()).isEqualTo(\"skidoo\");\n  }\n\n  enum Truthiness {\n    FALSY,\n    TRUTHY\n  }\n\n  @Retention(RetentionPolicy.RUNTIME)\n  @interface MyAnnotation {\n    String value();\n\n    int DEFAULT_ID = -1;\n\n    int id() default DEFAULT_ID;\n\n    Truthiness DEFAULT_TRUTHINESS = Truthiness.FALSY;\n\n    Truthiness truthiness() default Truthiness.FALSY;\n  }\n\n  // This method has a parameter for `truthiness`, even though that has a default, but it has no\n  // parameter for `id`, which also has a default.\n  @AutoAnnotation\n  static MyAnnotation myAnnotation(String value, Truthiness truthiness) {\n    return new AutoAnnotation_AutoBuilderTest_myAnnotation(value, truthiness);\n  }\n\n  // This method has parameters for all the annotation elements.\n  @AutoAnnotation\n  static MyAnnotation myAnnotationAll(String value, int id, Truthiness truthiness) {\n    return new AutoAnnotation_AutoBuilderTest_myAnnotationAll(value, id, truthiness);\n  }\n\n  @AutoBuilder(callMethod = \"myAnnotation\")\n  interface MyAnnotationBuilder {\n    MyAnnotationBuilder value(String x);\n\n    MyAnnotationBuilder truthiness(Truthiness x);\n\n    MyAnnotation build();\n  }\n\n  static MyAnnotationBuilder myAnnotationBuilder() {\n    return new AutoBuilder_AutoBuilderTest_MyAnnotationBuilder();\n  }\n\n  @AutoBuilder(callMethod = \"myAnnotationAll\")\n  interface MyAnnotationAllBuilder {\n    MyAnnotationAllBuilder value(String x);\n\n    MyAnnotationAllBuilder id(int x);\n\n    MyAnnotationAllBuilder truthiness(Truthiness x);\n\n    MyAnnotation build();\n  }\n\n  static MyAnnotationAllBuilder myAnnotationAllBuilder() {\n    return new AutoBuilder_AutoBuilderTest_MyAnnotationAllBuilder();\n  }\n\n  @Test\n  public void simpleAutoAnnotation() {\n    // We haven't supplied a value for `truthiness`, so AutoBuilder should use the default one in\n    // the annotation.\n    MyAnnotation annotation1 = myAnnotationBuilder().value(\"foo\").build();\n    assertThat(annotation1.value()).isEqualTo(\"foo\");\n    assertThat(annotation1.id()).isEqualTo(MyAnnotation.DEFAULT_ID);\n    assertThat(annotation1.truthiness()).isEqualTo(MyAnnotation.DEFAULT_TRUTHINESS);\n    MyAnnotation annotation2 =\n        myAnnotationBuilder().value(\"bar\").truthiness(Truthiness.TRUTHY).build();\n    assertThat(annotation2.value()).isEqualTo(\"bar\");\n    assertThat(annotation2.id()).isEqualTo(MyAnnotation.DEFAULT_ID);\n    assertThat(annotation2.truthiness()).isEqualTo(Truthiness.TRUTHY);\n\n    MyAnnotation annotation3 = myAnnotationAllBuilder().value(\"foo\").build();\n    MyAnnotation annotation4 =\n        myAnnotationAllBuilder()\n            .value(\"foo\")\n            .id(MyAnnotation.DEFAULT_ID)\n            .truthiness(MyAnnotation.DEFAULT_TRUTHINESS)\n            .build();\n    assertThat(annotation3).isEqualTo(annotation4);\n  }\n\n  @AutoBuilder(ofClass = MyAnnotation.class)\n  public interface MyAnnotationSimpleBuilder {\n    MyAnnotationSimpleBuilder value(String x);\n\n    MyAnnotationSimpleBuilder id(int x);\n\n    MyAnnotationSimpleBuilder truthiness(Truthiness x);\n\n    MyAnnotation build();\n  }\n\n  public static MyAnnotationSimpleBuilder myAnnotationSimpleBuilder() {\n    return new AutoBuilder_AutoBuilderTest_MyAnnotationSimpleBuilder();\n  }\n\n  @Test\n  public void buildWithoutAutoAnnotation() {\n    // We don't set a value for `id` or `truthiness`, so AutoBuilder should use the default ones in\n    // the annotation.\n    MyAnnotation annotation1 = myAnnotationSimpleBuilder().value(\"foo\").build();\n    assertThat(annotation1.value()).isEqualTo(\"foo\");\n    assertThat(annotation1.id()).isEqualTo(MyAnnotation.DEFAULT_ID);\n    assertThat(annotation1.truthiness()).isEqualTo(MyAnnotation.DEFAULT_TRUTHINESS);\n\n    // Now we set `truthiness` but still not `id`.\n    MyAnnotation annotation2 =\n        myAnnotationSimpleBuilder().value(\"bar\").truthiness(Truthiness.TRUTHY).build();\n    assertThat(annotation2.value()).isEqualTo(\"bar\");\n    assertThat(annotation2.id()).isEqualTo(MyAnnotation.DEFAULT_ID);\n    assertThat(annotation2.truthiness()).isEqualTo(Truthiness.TRUTHY);\n\n    // All three elements set explicitly.\n    MyAnnotation annotation3 =\n        myAnnotationSimpleBuilder().value(\"foo\").id(23).truthiness(Truthiness.TRUTHY).build();\n    assertThat(annotation3.value()).isEqualTo(\"foo\");\n    assertThat(annotation3.id()).isEqualTo(23);\n    assertThat(annotation3.truthiness()).isEqualTo(Truthiness.TRUTHY);\n  }\n\n  // This builder doesn't have a setter for the `truthiness` element, so the annotations it builds\n  // should always get the default value.\n  @AutoBuilder(ofClass = MyAnnotation.class)\n  public interface MyAnnotationSimplerBuilder {\n    MyAnnotationSimplerBuilder value(String x);\n\n    MyAnnotationSimplerBuilder id(int x);\n\n    MyAnnotation build();\n  }\n\n  public static MyAnnotationSimplerBuilder myAnnotationSimplerBuilder() {\n    return new AutoBuilder_AutoBuilderTest_MyAnnotationSimplerBuilder();\n  }\n\n  @Test\n  public void buildWithoutAutoAnnotation_noSetterForElement() {\n    MyAnnotation annotation = myAnnotationSimplerBuilder().value(\"foo\").id(23).build();\n    assertThat(annotation.value()).isEqualTo(\"foo\");\n    assertThat(annotation.id()).isEqualTo(23);\n    assertThat(annotation.truthiness()).isEqualTo(MyAnnotation.DEFAULT_TRUTHINESS);\n  }\n\n  static class Overload {\n    final int anInt;\n    final String aString;\n    final BigInteger aBigInteger;\n\n    Overload(int anInt, String aString) {\n      this(anInt, aString, BigInteger.ZERO);\n    }\n\n    Overload(int anInt, String aString, BigInteger aBigInteger) {\n      this.anInt = anInt;\n      this.aString = aString;\n      this.aBigInteger = aBigInteger;\n    }\n\n    @Override\n    public boolean equals(Object x) {\n      if (x instanceof Overload) {\n        Overload that = (Overload) x;\n        return this.anInt == that.anInt\n            && Objects.equals(this.aString, that.aString)\n            && Objects.equals(this.aBigInteger, that.aBigInteger);\n      }\n      return false;\n    }\n\n    @Override\n    public int hashCode() {\n      return Objects.hash(anInt, aString, aBigInteger);\n    }\n\n    @Override\n    public String toString() {\n      return MoreObjects.toStringHelper(this)\n          .add(\"anInt\", anInt)\n          .add(\"aString\", aString)\n          .add(\"aBigInteger\", aBigInteger)\n          .toString();\n    }\n\n    static Builder1 builder1() {\n      return new AutoBuilder_AutoBuilderTest_Overload_Builder1();\n    }\n\n    static Builder2 builder2() {\n      return new AutoBuilder_AutoBuilderTest_Overload_Builder2();\n    }\n\n    @AutoBuilder\n    interface Builder1 {\n      Builder1 setAnInt(int x);\n\n      Builder1 setAString(String x);\n\n      Overload build();\n    }\n\n    @AutoBuilder\n    interface Builder2 {\n      Builder2 setAnInt(int x);\n\n      Builder2 setAString(String x);\n\n      Builder2 setABigInteger(BigInteger x);\n\n      Overload build();\n    }\n  }\n\n  @Test\n  public void overloadedConstructor() {\n    Overload actual1 = Overload.builder1().setAnInt(23).setAString(\"skidoo\").build();\n    Overload expected1 = new Overload(23, \"skidoo\");\n    assertThat(actual1).isEqualTo(expected1);\n\n    BigInteger big17 = BigInteger.valueOf(17);\n    Overload actual2 =\n        Overload.builder2().setAnInt(17).setAString(\"17\").setABigInteger(big17).build();\n    Overload expected2 = new Overload(17, \"17\", big17);\n    assertThat(actual2).isEqualTo(expected2);\n  }\n\n  @AutoBuilder(callMethod = \"of\", ofClass = Simple.class)\n  interface SimpleStaticBuilder {\n    SimpleStaticBuilder anInt(int x);\n\n    SimpleStaticBuilder aString(String x);\n\n    Simple build();\n  }\n\n  static SimpleStaticBuilder simpleStaticBuilder() {\n    return new AutoBuilder_AutoBuilderTest_SimpleStaticBuilder();\n  }\n\n  @Test\n  public void staticMethod() {\n    Simple actual = simpleStaticBuilder().anInt(17).aString(\"17\").build();\n    Simple expected = new Simple(17, \"17\");\n    assertThat(actual).isEqualTo(expected);\n  }\n\n  // We can't be sure that the java.time package has parameter names, so we use this intermediary.\n  // Otherwise we could just write @AutoBuilder(callMethod = \"of\", ofClass = LocalTime.class).\n  // It's still interesting to test this as a realistic example.\n  static LocalTime localTimeOf(int hour, int minute, int second, int nanoOfSecond) {\n    return LocalTime.of(hour, minute, second, nanoOfSecond);\n  }\n\n  static LocalTimeBuilder localTimeBuilder() {\n    return new AutoBuilder_AutoBuilderTest_LocalTimeBuilder().nanoOfSecond(0);\n  }\n\n  @AutoBuilder(callMethod = \"localTimeOf\")\n  interface LocalTimeBuilder {\n    LocalTimeBuilder hour(int hour);\n\n    LocalTimeBuilder minute(int minute);\n\n    LocalTimeBuilder second(int second);\n\n    LocalTimeBuilder nanoOfSecond(int nanoOfSecond);\n\n    LocalTime build();\n  }\n\n  @Test\n  public void staticMethodOfContainingClass() {\n    LocalTime actual = localTimeBuilder().hour(12).minute(34).second(56).build();\n    LocalTime expected = LocalTime.of(12, 34, 56);\n    assertThat(actual).isEqualTo(expected);\n  }\n\n  @Test\n  public void missingRequiredProperty() {\n    IllegalStateException e =\n        assertThrows(\n            IllegalStateException.class, () -> localTimeBuilder().hour(12).minute(34).build());\n    assertThat(e).hasMessageThat().isEqualTo(\"Missing required properties: second\");\n  }\n\n  static void throwException() throws IOException {\n    throw new IOException(\"oops\");\n  }\n\n  static ThrowExceptionBuilder throwExceptionBuilder() {\n    return new AutoBuilder_AutoBuilderTest_ThrowExceptionBuilder();\n  }\n\n  @AutoBuilder(callMethod = \"throwException\")\n  interface ThrowExceptionBuilder {\n    void build() throws IOException;\n  }\n\n  @Test\n  public void emptyBuilderThrowsException() {\n    try {\n      throwExceptionBuilder().build();\n      fail();\n    } catch (IOException expected) {\n      assertThat(expected).hasMessageThat().isEqualTo(\"oops\");\n    }\n  }\n\n  static class ListContainer {\n    private final ImmutableList<String> list;\n\n    ListContainer(ImmutableList<String> list) {\n      this.list = checkNotNull(list);\n    }\n\n    @Override\n    public boolean equals(Object o) {\n      return o instanceof ListContainer && list.equals(((ListContainer) o).list);\n    }\n\n    @Override\n    public int hashCode() {\n      return list.hashCode();\n    }\n\n    @Override\n    public String toString() {\n      return list.toString();\n    }\n\n    static Builder builder() {\n      return new AutoBuilder_AutoBuilderTest_ListContainer_Builder();\n    }\n\n    @AutoBuilder\n    interface Builder {\n      Builder setList(Iterable<String> list);\n\n      ImmutableList.Builder<String> listBuilder();\n\n      ListContainer build();\n    }\n  }\n\n  @Test\n  public void propertyBuilder() {\n    ListContainer expected = new ListContainer(ImmutableList.of(\"one\", \"two\", \"three\"));\n    ListContainer actual1 =\n        ListContainer.builder().setList(ImmutableList.of(\"one\", \"two\", \"three\")).build();\n    assertThat(actual1).isEqualTo(expected);\n\n    ListContainer.Builder builder2 = ListContainer.builder();\n    builder2.listBuilder().add(\"one\", \"two\", \"three\");\n    assertThat(builder2.build()).isEqualTo(expected);\n\n    ListContainer.Builder builder3 = ListContainer.builder().setList(ImmutableList.of(\"one\"));\n    builder3.listBuilder().add(\"two\", \"three\");\n    assertThat(builder3.build()).isEqualTo(expected);\n\n    ListContainer.Builder builder4 = ListContainer.builder();\n    ImmutableList.Builder<String> unused = builder4.listBuilder();\n    try {\n      builder4.setList(ImmutableList.of(\"one\", \"two\", \"three\"));\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessageThat().isEqualTo(\"Cannot set list after calling listBuilder()\");\n    }\n  }\n\n  static <T> String concatList(ImmutableList<T> list) {\n    return list.stream().map(String::valueOf).collect(joining());\n  }\n\n  @AutoBuilder(callMethod = \"concatList\")\n  interface ConcatListCaller<T> {\n    ImmutableList.Builder<T> listBuilder();\n\n    String call();\n  }\n\n  @Test\n  public void propertyBuilderWithoutSetter() {\n    ConcatListCaller<Integer> caller = new AutoBuilder_AutoBuilderTest_ConcatListCaller<>();\n    caller.listBuilder().add(1, 1, 2, 3, 5, 8);\n    String s = caller.call();\n    assertThat(s).isEqualTo(\"112358\");\n  }\n\n  static <K, V extends Number> Map<K, V> singletonMap(K key, V value) {\n    return Collections.singletonMap(key, value);\n  }\n\n  static <K, V extends Number> SingletonMapBuilder<K, V> singletonMapBuilder() {\n    return new AutoBuilder_AutoBuilderTest_SingletonMapBuilder<>();\n  }\n\n  @AutoBuilder(callMethod = \"singletonMap\")\n  interface SingletonMapBuilder<K, V extends Number> {\n    SingletonMapBuilder<K, V> key(K key);\n\n    SingletonMapBuilder<K, V> value(V value);\n\n    Map<K, V> build();\n  }\n\n  @Test\n  public void genericStaticMethod() {\n    ImmutableMap<String, Integer> expected = ImmutableMap.of(\"17\", 17);\n    SingletonMapBuilder<String, Integer> builder = singletonMapBuilder();\n    Map<String, Integer> actual = builder.key(\"17\").value(17).build();\n    assertThat(actual).isEqualTo(expected);\n  }\n\n  static class SingletonSet<E> extends AbstractSet<E> {\n    private final E element;\n\n    SingletonSet(E element) {\n      this.element = element;\n    }\n\n    @Override\n    public int size() {\n      return 1;\n    }\n\n    @Override\n    public Iterator<E> iterator() {\n      return new Iterator<E>() {\n        private boolean first = true;\n\n        @Override\n        public boolean hasNext() {\n          return first;\n        }\n\n        @Override\n        public E next() {\n          if (!first) {\n            throw new NoSuchElementException();\n          }\n          first = false;\n          return element;\n        }\n      };\n    }\n  }\n\n  @AutoBuilder(ofClass = SingletonSet.class)\n  interface SingletonSetBuilder<E> {\n    SingletonSetBuilder<E> setElement(E element);\n\n    SingletonSet<E> build();\n  }\n\n  static <E> SingletonSetBuilder<E> singletonSetBuilder() {\n    return new AutoBuilder_AutoBuilderTest_SingletonSetBuilder<>();\n  }\n\n  @Test\n  public void genericClass() {\n    ImmutableSet<String> expected = ImmutableSet.of(\"foo\");\n    SingletonSetBuilder<String> builder = singletonSetBuilder();\n    Set<String> actual = builder.setElement(\"foo\").build();\n    assertThat(actual).isEqualTo(expected);\n  }\n\n  static class TypedSingletonSet<E> extends SingletonSet<E> {\n    private final Class<?> type;\n\n    <T extends E> TypedSingletonSet(T element, Class<T> type) {\n      super(element);\n      this.type = type;\n    }\n\n    @Override\n    public String toString() {\n      return type.getName() + super.toString();\n    }\n  }\n\n  @AutoBuilder(ofClass = TypedSingletonSet.class)\n  interface TypedSingletonSetBuilder<E, T extends E> {\n    TypedSingletonSetBuilder<E, T> setElement(T element);\n\n    TypedSingletonSetBuilder<E, T> setType(Class<T> type);\n\n    TypedSingletonSet<E> build();\n  }\n\n  static <E, T extends E> TypedSingletonSetBuilder<E, T> typedSingletonSetBuilder() {\n    return new AutoBuilder_AutoBuilderTest_TypedSingletonSetBuilder<>();\n  }\n\n  @Test\n  public void genericClassWithGenericConstructor() {\n    TypedSingletonSetBuilder<CharSequence, String> builder = typedSingletonSetBuilder();\n    TypedSingletonSet<CharSequence> set = builder.setElement(\"foo\").setType(String.class).build();\n    assertThat(set.toString()).isEqualTo(\"java.lang.String[foo]\");\n  }\n\n  static <T> ImmutableList<T> pair(T first, T second) {\n    return ImmutableList.of(first, second);\n  }\n\n  @AutoBuilder(callMethod = \"pair\")\n  interface PairBuilder<T> {\n    PairBuilder<T> setFirst(T x);\n\n    T getFirst();\n\n    PairBuilder<T> setSecond(T x);\n\n    Optional<T> getSecond();\n\n    ImmutableList<T> build();\n  }\n\n  static <T> PairBuilder<T> pairBuilder() {\n    return new AutoBuilder_AutoBuilderTest_PairBuilder<>();\n  }\n\n  @Test\n  public void genericGetters() {\n    PairBuilder<Number> builder = pairBuilder();\n    Truth.assertThat(builder.getSecond()).isEmpty();\n    builder.setSecond(2);\n    Truth.assertThat(builder.getSecond()).hasValue(2);\n    try {\n      builder.getFirst();\n      fail();\n    } catch (IllegalStateException expected) {\n    }\n    builder.setFirst(1.0);\n    assertThat(builder.getFirst()).isEqualTo(1.0);\n    assertThat(builder.build()).containsExactly(1.0, 2).inOrder();\n  }\n\n  static class NumberHolder<T extends Number> {\n    private final T number;\n\n    NumberHolder(T number) {\n      this.number = number;\n    }\n\n    T getNumber() {\n      return number;\n    }\n  }\n\n  static <T extends Number> NumberHolder<T> buildNumberHolder(T number) {\n    return new NumberHolder<>(number);\n  }\n\n  @AutoBuilder(callMethod = \"buildNumberHolder\")\n  interface NumberHolderBuilder<T extends Number> {\n    NumberHolderBuilder<T> setNumber(T number);\n\n    NumberHolder<T> build();\n  }\n\n  static <T extends Number> NumberHolderBuilder<T> numberHolderBuilder() {\n    return new AutoBuilder_AutoBuilderTest_NumberHolderBuilder<>();\n  }\n\n  static <T extends Number> NumberHolderBuilder<T> numberHolderBuilder(\n      NumberHolder<T> numberHolder) {\n    return new AutoBuilder_AutoBuilderTest_NumberHolderBuilder<>(numberHolder);\n  }\n\n  @Test\n  public void builderFromInstance() {\n    NumberHolder<Integer> instance1 =\n        AutoBuilderTest.<Integer>numberHolderBuilder().setNumber(23).build();\n    assertThat(instance1.getNumber()).isEqualTo(23);\n    NumberHolder<Integer> instance2 = numberHolderBuilder(instance1).build();\n    assertThat(instance2.getNumber()).isEqualTo(23);\n    NumberHolder<Integer> instance3 = numberHolderBuilder(instance2).setNumber(17).build();\n    assertThat(instance3.getNumber()).isEqualTo(17);\n  }\n\n  @AutoBuilder(callMethod = \"of\", ofClass = Simple.class)\n  @MyAnnotation(\"thing\")\n  interface AnnotatedSimpleStaticBuilder1 {\n    AnnotatedSimpleStaticBuilder1 anInt(int x);\n\n    AnnotatedSimpleStaticBuilder1 aString(String x);\n\n    Simple build();\n  }\n\n  @Test\n  public void builderAnnotationsNotCopiedByDefault() {\n    assertThat(AutoBuilder_AutoBuilderTest_AnnotatedSimpleStaticBuilder1.class.getAnnotations())\n        .asList()\n        .isEmpty();\n  }\n\n  @AutoBuilder(callMethod = \"of\", ofClass = Simple.class)\n  @AutoValue.CopyAnnotations\n  @MyAnnotation(\"thing\")\n  interface AnnotatedSimpleStaticBuilder2 {\n    AnnotatedSimpleStaticBuilder2 anInt(int x);\n\n    AnnotatedSimpleStaticBuilder2 aString(String x);\n\n    Simple build();\n  }\n\n  @Test\n  public void builderAnnotationsCopiedIfRequested() {\n    assertThat(AutoBuilder_AutoBuilderTest_AnnotatedSimpleStaticBuilder2.class.getAnnotations())\n        .asList()\n        .contains(myAnnotationBuilder().value(\"thing\").build());\n  }\n\n  @Target(TYPE_USE)\n  public @interface Nullable {}\n\n  public static <T extends @Nullable Object, U> T frob(T arg, U notNull) {\n    return arg;\n  }\n\n  @AutoBuilder(callMethod = \"frob\")\n  interface FrobCaller<T extends @Nullable Object, U> {\n    FrobCaller<T, U> arg(T arg);\n\n    FrobCaller<T, U> notNull(U notNull);\n\n    T call();\n\n    static <T extends @Nullable Object, U> FrobCaller<T, U> caller() {\n      return new AutoBuilder_AutoBuilderTest_FrobCaller<>();\n    }\n  }\n\n  @Test\n  public void builderTypeVariableWithNullableBound() {\n    // The Annotation Processing API doesn't see the @Nullable Object bound on Java 8.\n    assumeTrue(SourceVersion.latest().ordinal() > SourceVersion.RELEASE_8.ordinal());\n    assertThat(FrobCaller.<@Nullable String, String>caller().arg(null).notNull(\"foo\").call())\n        .isNull();\n    assertThrows(\n        NullPointerException.class,\n        () -> FrobCaller.<@Nullable String, String>caller().arg(null).notNull(null).call());\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/AutoOneOfJava8Test.java",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value;\n\nimport static com.google.common.truth.Truth.assertThat;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\nimport java.lang.reflect.AnnotatedType;\nimport java.lang.reflect.Method;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * Tests for Java8-specific {@code @AutoOneOf} behaviour.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class AutoOneOfJava8Test {\n  @AutoOneOf(EqualsNullable.Kind.class)\n  public abstract static class EqualsNullable {\n\n    @Target(ElementType.TYPE_USE)\n    @Retention(RetentionPolicy.RUNTIME)\n    public @interface Nullable {}\n\n    public enum Kind {\n      THING\n    }\n\n    public abstract Kind kind();\n\n    public abstract String thing();\n\n    public static EqualsNullable ofThing(String thing) {\n      return AutoOneOf_AutoOneOfJava8Test_EqualsNullable.thing(thing);\n    }\n\n    @Override\n    public abstract boolean equals(@Nullable Object x);\n\n    @Override\n    public abstract int hashCode();\n  }\n\n  /**\n   * Tests that a type annotation on the parameter of {@code equals(Object)} is copied into the\n   * implementation class.\n   */\n  @Test\n  public void equalsNullable() throws ReflectiveOperationException {\n    EqualsNullable x = EqualsNullable.ofThing(\"foo\");\n    Class<? extends EqualsNullable> c = x.getClass();\n    Method equals = c.getMethod(\"equals\", Object.class);\n    assertThat(equals.getDeclaringClass()).isNotSameInstanceAs(EqualsNullable.class);\n    AnnotatedType parameterType = equals.getAnnotatedParameterTypes()[0];\n    assertThat(parameterType.isAnnotationPresent(EqualsNullable.Nullable.class)).isTrue();\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/AutoOneOfTest.java",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.fail;\n\nimport com.google.common.testing.EqualsTester;\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\nimport java.io.Serializable;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.util.concurrent.ExecutionException;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class AutoOneOfTest {\n  @AutoValue\n  public abstract static class Dog {\n    public abstract String name();\n\n    public static Dog create(String name) {\n      return new AutoValue_AutoOneOfTest_Dog(name);\n    }\n\n    public void bark() {}\n  }\n\n  @AutoValue\n  public abstract static class Cat {\n    public static Cat create() {\n      return new AutoValue_AutoOneOfTest_Cat();\n    }\n\n    public void meow() {}\n  }\n\n  @AutoValue\n  public abstract static class TigerShark {\n    public static TigerShark create() {\n      return new AutoValue_AutoOneOfTest_TigerShark();\n    }\n\n    public void chomp() {}\n  }\n\n  @AutoOneOf(Pet.Kind.class)\n  public abstract static class Pet {\n\n    public static Pet create(Dog dog) {\n      return AutoOneOf_AutoOneOfTest_Pet.dog(dog);\n    }\n\n    public static Pet create(Cat cat) {\n      return AutoOneOf_AutoOneOfTest_Pet.cat(cat);\n    }\n\n    public static Pet create(TigerShark shark) {\n      return AutoOneOf_AutoOneOfTest_Pet.tigerShark(shark);\n    }\n\n    public abstract Dog dog();\n\n    public abstract Cat cat();\n\n    public abstract TigerShark tigerShark();\n\n    public enum Kind {\n      DOG,\n      CAT,\n      TIGER_SHARK\n    }\n\n    public abstract Kind getKind();\n  }\n\n  @Test\n  public void equality() {\n    Dog marvin1 = Dog.create(\"Marvin\");\n    Pet petMarvin1 = Pet.create(marvin1);\n    Dog marvin2 = Dog.create(\"Marvin\");\n    Pet petMarvin2 = Pet.create(marvin2);\n    Dog isis = Dog.create(\"Isis\");\n    Pet petIsis = Pet.create(isis);\n    Cat cat = Cat.create();\n    new EqualsTester()\n        .addEqualityGroup(marvin1, marvin2)\n        .addEqualityGroup(petMarvin1, petMarvin2)\n        .addEqualityGroup(petIsis)\n        .addEqualityGroup(cat)\n        .addEqualityGroup(\"foo\")\n        .testEquals();\n  }\n\n  @Test\n  public void getCorrectType() {\n    Dog marvin = Dog.create(\"Marvin\");\n    Pet petMarvin = Pet.create(marvin);\n    assertThat(petMarvin.dog()).isSameInstanceAs(marvin);\n  }\n\n  @Test\n  public void getWrongType() {\n    Cat cat = Cat.create();\n    Pet petCat = Pet.create(cat);\n    try {\n      petCat.tigerShark();\n      fail();\n    } catch (UnsupportedOperationException e) {\n      assertThat(e).hasMessageThat().containsMatch(\"(?i:cat)\");\n    }\n  }\n\n  @Test\n  public void string() {\n    Dog marvin = Dog.create(\"Marvin\");\n    Pet petMarvin = Pet.create(marvin);\n    assertThat(petMarvin.toString()).isEqualTo(\"Pet{dog=Dog{name=Marvin}}\");\n  }\n\n  @Test\n  public void getKind() {\n    Dog marvin = Dog.create(\"Marvin\");\n    Pet petMarvin = Pet.create(marvin);\n    Cat cat = Cat.create();\n    Pet petCat = Pet.create(cat);\n    TigerShark shark = TigerShark.create();\n    Pet petShark = Pet.create(shark);\n    assertThat(petMarvin.getKind()).isEqualTo(Pet.Kind.DOG);\n    assertThat(petCat.getKind()).isEqualTo(Pet.Kind.CAT);\n    assertThat(petShark.getKind()).isEqualTo(Pet.Kind.TIGER_SHARK);\n  }\n\n  @Test\n  public void cannotBeNull() {\n    try {\n      Pet.create((Dog) null);\n      fail();\n    } catch (NullPointerException expected) {\n    }\n  }\n\n  // Package-private case.\n\n  @AutoOneOf(IntegerOrString.Kind.class)\n  abstract static class IntegerOrString {\n    enum Kind {\n      INTEGER,\n      STRING\n    }\n\n    abstract Kind getKind();\n\n    abstract int integer();\n\n    abstract String string();\n\n    static IntegerOrString of(int x) {\n      return AutoOneOf_AutoOneOfTest_IntegerOrString.integer(x);\n    }\n\n    static IntegerOrString of(String x) {\n      return AutoOneOf_AutoOneOfTest_IntegerOrString.string(x);\n    }\n  }\n\n  @Test\n  public void packagePrivate() {\n    IntegerOrString integer = IntegerOrString.of(23);\n    IntegerOrString string = IntegerOrString.of(\"23\");\n    assertThat(integer.getKind()).isEqualTo(IntegerOrString.Kind.INTEGER);\n    assertThat(string.getKind()).isEqualTo(IntegerOrString.Kind.STRING);\n    assertThat(integer.integer()).isEqualTo(23);\n    assertThat(string.string()).isEqualTo(\"23\");\n    assertThat(integer).isNotEqualTo(string);\n    try {\n      integer.string();\n      fail();\n    } catch (UnsupportedOperationException e) {\n      assertThat(e).hasMessageThat().containsMatch(\"(?i:integer)\");\n    }\n  }\n\n  @AutoOneOf(Pet.Kind.class)\n  public abstract static class PetWithGet {\n    public abstract Dog getDog();\n\n    public abstract Cat getCat();\n\n    public abstract TigerShark getTigerShark();\n\n    public static PetWithGet create(Dog dog) {\n      return AutoOneOf_AutoOneOfTest_PetWithGet.dog(dog);\n    }\n\n    public static PetWithGet create(Cat cat) {\n      return AutoOneOf_AutoOneOfTest_PetWithGet.cat(cat);\n    }\n\n    public static PetWithGet create(TigerShark shark) {\n      return AutoOneOf_AutoOneOfTest_PetWithGet.tigerShark(shark);\n    }\n\n    public abstract Pet.Kind getKind();\n  }\n\n  @Test\n  public void getPrefix() {\n    Dog marvin = Dog.create(\"Marvin\");\n    PetWithGet petMarvin = PetWithGet.create(marvin);\n    assertThat(petMarvin.toString()).isEqualTo(\"PetWithGet{dog=Dog{name=Marvin}}\");\n  }\n\n  @AutoOneOf(Primitive.Kind.class)\n  public abstract static class Primitive {\n    public enum Kind {\n      A_BYTE,\n      A_SHORT,\n      AN_INT,\n      A_LONG,\n      A_FLOAT,\n      A_DOUBLE,\n      A_CHAR,\n      A_BOOLEAN\n    }\n\n    public abstract Kind getKind();\n\n    public abstract byte aByte();\n\n    public abstract short aShort();\n\n    public abstract int anInt();\n\n    public abstract long aLong();\n\n    public abstract float aFloat();\n\n    public abstract double aDouble();\n\n    public abstract char aChar();\n\n    public abstract boolean aBoolean();\n\n    public static Primitive of(byte x) {\n      return AutoOneOf_AutoOneOfTest_Primitive.aByte(x);\n    }\n\n    public static Primitive of(short x) {\n      return AutoOneOf_AutoOneOfTest_Primitive.aShort(x);\n    }\n\n    public static Primitive of(int x) {\n      return AutoOneOf_AutoOneOfTest_Primitive.anInt(x);\n    }\n\n    public static Primitive of(long x) {\n      return AutoOneOf_AutoOneOfTest_Primitive.aLong(x);\n    }\n\n    public static Primitive of(float x) {\n      return AutoOneOf_AutoOneOfTest_Primitive.aFloat(x);\n    }\n\n    public static Primitive of(double x) {\n      return AutoOneOf_AutoOneOfTest_Primitive.aDouble(x);\n    }\n\n    public static Primitive of(char x) {\n      return AutoOneOf_AutoOneOfTest_Primitive.aChar(x);\n    }\n\n    public static Primitive of(boolean x) {\n      return AutoOneOf_AutoOneOfTest_Primitive.aBoolean(x);\n    }\n  }\n\n  @Test\n  public void primitive() {\n    Primitive primitive = Primitive.of(17);\n    assertThat(primitive.anInt()).isEqualTo(17);\n    assertThat(primitive.toString()).isEqualTo(\"Primitive{anInt=17}\");\n  }\n\n  @AutoOneOf(OneOfOne.Kind.class)\n  public abstract static class OneOfOne {\n    public enum Kind {\n      DOG\n    }\n\n    public abstract Dog getDog();\n\n    public static OneOfOne create(Dog dog) {\n      return AutoOneOf_AutoOneOfTest_OneOfOne.dog(dog);\n    }\n\n    public abstract Kind getKind();\n  }\n\n  @Test\n  public void oneOfOne() {\n    Dog marvin = Dog.create(\"Marvin\");\n    OneOfOne oneOfMarvin = OneOfOne.create(marvin);\n    assertThat(oneOfMarvin.toString()).isEqualTo(\"OneOfOne{dog=Dog{name=Marvin}}\");\n    assertThat(oneOfMarvin.getKind()).isEqualTo(OneOfOne.Kind.DOG);\n  }\n\n  // We allow this for consistency, even though it's obviously pretty useless.\n  // The generated code might be rubbish, but it compiles. No concrete implementation is generated\n  // so there isn't really anything to test beyond that it compiles.\n  @AutoOneOf(OneOfNone.Kind.class)\n  public abstract static class OneOfNone {\n    public enum Kind {}\n\n    public abstract Kind getKind();\n  }\n\n  // Testing generics. Typically generics will be a bit messy because the @AutoOneOf class must\n  // have type parameters for every property that needs them, even though any given property\n  // might not use all the type parameters.\n  @AutoOneOf(TaskResult.Kind.class)\n  public abstract static class TaskResult<V extends Serializable> {\n    public enum Kind {\n      VALUE,\n      EXCEPTION\n    }\n\n    public abstract Kind getKind();\n\n    public abstract V value();\n\n    public abstract Throwable exception();\n\n    public V get() throws ExecutionException {\n      switch (getKind()) {\n        case VALUE:\n          return value();\n        case EXCEPTION:\n          throw new ExecutionException(exception());\n      }\n      throw new AssertionError(getKind());\n    }\n\n    static <V extends Serializable> TaskResult<V> value(V value) {\n      return AutoOneOf_AutoOneOfTest_TaskResult.value(value);\n    }\n\n    static TaskResult<?> exception(Throwable exception) {\n      return AutoOneOf_AutoOneOfTest_TaskResult.exception(exception);\n    }\n  }\n\n  @Test\n  public void taskResultValue() throws Exception {\n    TaskResult<String> result = TaskResult.value(\"foo\");\n    assertThat(result.get()).isEqualTo(\"foo\");\n  }\n\n  @Test\n  public void taskResultException() {\n    Exception exception = new IllegalArgumentException(\"oops\");\n    TaskResult<?> result = TaskResult.exception(exception);\n    try {\n      result.get();\n      fail();\n    } catch (ExecutionException e) {\n      assertThat(e).hasCauseThat().isEqualTo(exception);\n    }\n  }\n\n  @AutoOneOf(CustomToString.Kind.class)\n  public abstract static class CustomToString {\n    public enum Kind {\n      ACE\n    }\n\n    public abstract Kind getKind();\n\n    public abstract String ace();\n\n    public static CustomToString ace(String ace) {\n      return AutoOneOf_AutoOneOfTest_CustomToString.ace(ace);\n    }\n\n    @Override\n    public String toString() {\n      return \"blim\";\n    }\n  }\n\n  // If you have an explicit toString() method, we won't override it.\n  @Test\n  public void customToString() {\n    CustomToString x = CustomToString.ace(\"ceg\");\n    assertThat(x.toString()).isEqualTo(\"blim\");\n  }\n\n  @AutoOneOf(AbstractToString.Kind.class)\n  public abstract static class AbstractToString {\n    public enum Kind {\n      ACE\n    }\n\n    public abstract Kind getKind();\n\n    public abstract String ace();\n\n    public static AbstractToString ace(String ace) {\n      return AutoOneOf_AutoOneOfTest_AbstractToString.ace(ace);\n    }\n\n    @Override\n    public abstract String toString();\n  }\n\n  // If you have an explicit abstract toString() method, we will implement it.\n  @Test\n  public void abstractToString() {\n    AbstractToString x = AbstractToString.ace(\"ceg\");\n    assertThat(x.toString()).isEqualTo(\"AbstractToString{ace=ceg}\");\n  }\n\n  // \"package\" is a reserved word. You probably don't want to have a property with that name,\n  // but if you insist, you can get one by using getFoo()-style methods. We leak our renaming\n  // scheme here (package0) and for users that that bothers they can just avoid having properties\n  // that are reserved words.\n  @AutoOneOf(LetterOrPackage.Kind.class)\n  public abstract static class LetterOrPackage {\n    public enum Kind {\n      LETTER,\n      PACKAGE\n    }\n\n    public abstract Kind getKind();\n\n    public abstract String getLetter();\n\n    public abstract String getPackage();\n\n    public static LetterOrPackage ofLetter(String letter) {\n      return AutoOneOf_AutoOneOfTest_LetterOrPackage.letter(letter);\n    }\n\n    public static LetterOrPackage ofPackage(String pkg) {\n      return AutoOneOf_AutoOneOfTest_LetterOrPackage.package0(pkg);\n    }\n  }\n\n  @Test\n  public void reservedWordProperty() {\n    LetterOrPackage pkg = LetterOrPackage.ofPackage(\"pacquet\");\n    assertThat(pkg.toString()).isEqualTo(\"LetterOrPackage{package=pacquet}\");\n  }\n\n  @AutoOneOf(ArrayValue.Kind.class)\n  public abstract static class ArrayValue {\n    public enum Kind {\n      STRING,\n      INTS\n    }\n\n    public abstract Kind getKind();\n\n    public abstract String string();\n\n    @SuppressWarnings(\"mutable\")\n    public abstract int[] ints();\n\n    public static ArrayValue ofString(String string) {\n      return AutoOneOf_AutoOneOfTest_ArrayValue.string(string);\n    }\n\n    public static ArrayValue ofInts(int[] ints) {\n      return AutoOneOf_AutoOneOfTest_ArrayValue.ints(ints);\n    }\n  }\n\n  @Test\n  public void arrayValues() {\n    ArrayValue string = ArrayValue.ofString(\"foo\");\n    ArrayValue ints1 = ArrayValue.ofInts(new int[] {17, 23});\n    ArrayValue ints2 = ArrayValue.ofInts(new int[] {17, 23});\n    new EqualsTester().addEqualityGroup(string).addEqualityGroup(ints1, ints2).testEquals();\n  }\n\n  @Retention(RetentionPolicy.RUNTIME)\n  public @interface CopyTest {\n    int value();\n  }\n\n  @AutoOneOf(AnnotationNotCopied.Kind.class)\n  @CopyTest(23)\n  public abstract static class AnnotationNotCopied {\n    public enum Kind {\n      ACE\n    }\n\n    public abstract Kind getKind();\n\n    public abstract String ace();\n\n    public static AnnotationNotCopied ace(String ace) {\n      return AutoOneOf_AutoOneOfTest_AnnotationNotCopied.ace(ace);\n    }\n  }\n\n  @Test\n  public void classAnnotationsNotCopiedByDefault() {\n    assertThat(AnnotationNotCopied.class.isAnnotationPresent(CopyTest.class)).isTrue();\n    AnnotationNotCopied ace = AnnotationNotCopied.ace(\"ace\");\n    assertThat(ace.getClass().isAnnotationPresent(CopyTest.class)).isFalse();\n  }\n\n  @AutoOneOf(AnnotationCopied.Kind.class)\n  @CopyTest(23)\n  @AutoValue.CopyAnnotations\n  public abstract static class AnnotationCopied {\n    public enum Kind {\n      ACE\n    }\n\n    public abstract Kind getKind();\n\n    public abstract String ace();\n\n    public static AnnotationCopied ace(String ace) {\n      return AutoOneOf_AutoOneOfTest_AnnotationCopied.ace(ace);\n    }\n  }\n\n  @Test\n  public void classAnnotationsCopiedIfCopyAnnotations() {\n    assertThat(AnnotationCopied.class.isAnnotationPresent(CopyTest.class)).isTrue();\n    AnnotationCopied ace = AnnotationCopied.ace(\"ace\");\n    assertThat(ace.getClass().isAnnotationPresent(CopyTest.class)).isTrue();\n    assertThat(ace.getClass().getAnnotation(CopyTest.class).value()).isEqualTo(23);\n  }\n\n  @AutoOneOf(MaybeEmpty.Kind.class)\n  public abstract static class MaybeEmpty implements Serializable {\n    private static final long serialVersionUID = 1L;\n\n    public enum Kind {\n      EMPTY,\n      STRING,\n    }\n\n    public abstract Kind getKind();\n\n    public abstract void empty();\n\n    public abstract String string();\n\n    public static MaybeEmpty ofEmpty() {\n      return AutoOneOf_AutoOneOfTest_MaybeEmpty.empty();\n    }\n\n    public static MaybeEmpty ofString(String s) {\n      return AutoOneOf_AutoOneOfTest_MaybeEmpty.string(s);\n    }\n  }\n\n  @Test\n  public void voidPropertyIsSingleton() {\n    MaybeEmpty empty1 = MaybeEmpty.ofEmpty();\n    MaybeEmpty empty2 = MaybeEmpty.ofEmpty();\n    assertThat(empty1).isSameInstanceAs(empty2);\n  }\n\n  @Test\n  public void voidPropertyRemainsSingletonWhenDeserialized() throws Exception {\n    MaybeEmpty empty1 = MaybeEmpty.ofEmpty();\n    ByteArrayOutputStream baos = new ByteArrayOutputStream();\n    // We're still compiling this with -source 6, so we can't use try-with-resources.\n    ObjectOutputStream dos = new ObjectOutputStream(baos);\n    dos.writeObject(empty1);\n    dos.close();\n    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());\n    ObjectInputStream ois = new ObjectInputStream(bais);\n    MaybeEmpty empty2 = (MaybeEmpty) ois.readObject();\n    assertThat(empty2).isSameInstanceAs(empty1);\n  }\n\n  @Test\n  public void voidPropertyToString() {\n    MaybeEmpty empty = MaybeEmpty.ofEmpty();\n    assertThat(empty.toString()).isEqualTo(\"MaybeEmpty{empty}\");\n  }\n\n  @Test\n  public void voidPropertyHashCodeIsIdentity() {\n    MaybeEmpty empty = MaybeEmpty.ofEmpty();\n    assertThat(empty.hashCode()).isEqualTo(System.identityHashCode(empty));\n  }\n\n  @Test\n  public void voidPropertyGetterDoesNothing() {\n    MaybeEmpty empty = MaybeEmpty.ofEmpty();\n    empty.empty();\n  }\n\n  @Test\n  public void voidPropertyNotEqualToNonVoid() {\n    MaybeEmpty empty = MaybeEmpty.ofEmpty();\n    MaybeEmpty notEmpty = MaybeEmpty.ofString(\"foo\");\n    assertThat(empty).isNotEqualTo(notEmpty);\n    assertThat(notEmpty).isNotEqualTo(empty);\n  }\n\n  @Test\n  public void voidPropertyWrongType() {\n    MaybeEmpty notEmpty = MaybeEmpty.ofString(\"foo\");\n    try {\n      notEmpty.empty();\n      fail();\n    } catch (UnsupportedOperationException e) {\n      assertThat(e).hasMessageThat().containsMatch(\"(?i:string)\");\n    }\n  }\n\n  @AutoOneOf(OneOfArray.Kind.class)\n  public abstract static class OneOfArray {\n    public enum Kind {\n      INTS\n    }\n\n    public abstract Kind getKind();\n\n    @SuppressWarnings(\"mutable\")\n    public abstract int[] ints();\n\n    public static OneOfArray ofInts(int[] s) {\n      return AutoOneOf_AutoOneOfTest_OneOfArray.ints(s);\n    }\n  }\n\n  @Test\n  public void arrayToString() {\n    OneOfArray oneOfArray = OneOfArray.ofInts(new int[] {1, 2});\n    assertThat(oneOfArray.toString()).isEqualTo(\"OneOfArray{ints=[1, 2]}\");\n  }\n\n  @AutoOneOf(OneOfFunkyString.Kind.class)\n  public abstract static class OneOfFunkyString {\n    public enum Kind {\n      FUNKY_STRING\n    }\n\n    public static class String {}\n\n    public abstract Kind getKind();\n\n    public abstract String funkyString();\n\n    public static OneOfFunkyString ofFunkyString(String s) {\n      return AutoOneOf_AutoOneOfTest_OneOfFunkyString.funkyString(s);\n    }\n  }\n\n  @Test\n  public void funkyString() {\n    OneOfFunkyString oneOfFunkyString =\n        OneOfFunkyString.ofFunkyString(new OneOfFunkyString.String());\n    assertThat(oneOfFunkyString.funkyString()).isNotNull();\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/AutoValueJava8Test.java",
    "content": "/*\n * Copyright 2012 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value;\n\nimport static com.google.common.base.StandardSystemProperty.JAVA_SPECIFICATION_VERSION;\nimport static com.google.common.collect.ImmutableSet.toImmutableSet;\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.common.truth.Truth.assertWithMessage;\nimport static com.google.common.truth.TruthJUnit.assume;\nimport static com.google.testing.compile.CompilationSubject.assertThat;\nimport static java.util.Arrays.stream;\nimport static org.junit.Assert.assertThrows;\nimport static org.junit.Assume.assumeTrue;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Iterables;\nimport com.google.common.testing.EqualsTester;\nimport com.google.common.truth.Truth;\nimport com.google.testing.compile.Compilation;\nimport com.google.testing.compile.Compiler;\nimport com.google.testing.compile.JavaFileObjects;\nimport java.io.Serializable;\nimport java.lang.annotation.Annotation;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\nimport java.lang.reflect.AnnotatedParameterizedType;\nimport java.lang.reflect.AnnotatedType;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.TypeVariable;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.Optional;\nimport java.util.OptionalDouble;\nimport java.util.Set;\nimport java.util.function.Predicate;\nimport java.util.stream.Stream;\nimport javax.annotation.processing.AbstractProcessor;\nimport javax.annotation.processing.RoundEnvironment;\nimport javax.annotation.processing.SupportedAnnotationTypes;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.util.ElementFilter;\nimport javax.tools.Diagnostic;\nimport javax.tools.JavaFileObject;\nimport org.junit.AssumptionViolatedException;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * Tests for constructs new in Java 8, such as type annotations.\n *\n * @author Till Brychcy\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\n@SuppressWarnings({\"SameNameButDifferent\", \"NullableTypeParameter\", \"TruthSelfEquals\"})\n// We are deliberately doing some shady stuff to test edge cases.\npublic class AutoValueJava8Test {\n  @SuppressWarnings(\"NonFinalStaticField\") // b/314784069\n  private static boolean javacHandlesTypeAnnotationsCorrectly;\n\n  // This is appalling. Some versions of javac do not correctly report annotations on type uses in\n  // certain cases, for example on type variables or arrays. Since some of the tests here are for\n  // exactly that, we compile a test program with a test annotation processor to see whether we\n  // might be in the presence of such a javac, and if so we skip the tests that would fail because\n  // of the bug. This isn't completely sound because we can't be entirely sure that the javac that\n  // Compiler.javac() finds is the same as the javac that was used to build this test (and therefore\n  // run AutoValueProcessor), but it's better than just ignoring the tests outright.\n  @BeforeClass\n  public static void setUpClass() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"Test\",\n            \"import java.lang.annotation.ElementType;\",\n            \"import java.lang.annotation.Retention;\",\n            \"import java.lang.annotation.RetentionPolicy;\",\n            \"import java.lang.annotation.Target;\",\n            \"public abstract class Test<T> {\",\n            \"  @Retention(RetentionPolicy.RUNTIME)\",\n            \"  @Target(ElementType.TYPE_USE)\",\n            \"  public @interface Nullable {}\",\n            \"\",\n            \"  public abstract @Nullable T t();\",\n            \"}\");\n    Compilation compilation =\n        Compiler.javac().withProcessors(new BugTestProcessor()).compile(javaFileObject);\n    if (compilation.errors().isEmpty()) {\n      javacHandlesTypeAnnotationsCorrectly = true;\n    } else {\n      assertThat(compilation).hadErrorCount(1);\n      assertThat(compilation).hadErrorContaining(JAVAC_HAS_BUG_ERROR);\n    }\n  }\n\n  private static final String JAVAC_HAS_BUG_ERROR = \"javac has the type-annotation bug\";\n\n  @SupportedAnnotationTypes(\"*\")\n  private static class BugTestProcessor extends AbstractProcessor {\n\n    @Override\n    public SourceVersion getSupportedSourceVersion() {\n      return SourceVersion.latestSupported();\n    }\n\n    @Override\n    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n      if (roundEnv.processingOver()) {\n        test();\n      }\n      return false;\n    }\n\n    private void test() {\n      TypeElement test = processingEnv.getElementUtils().getTypeElement(\"Test\");\n      List<ExecutableElement> methods = ElementFilter.methodsIn(test.getEnclosedElements());\n      ExecutableElement t = Iterables.getOnlyElement(methods);\n      assertThat(t.getSimpleName().toString()).isEqualTo(\"t\");\n      List<? extends AnnotationMirror> typeAnnotations = t.getReturnType().getAnnotationMirrors();\n      if (typeAnnotations.isEmpty()) {\n        processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, JAVAC_HAS_BUG_ERROR);\n        return;\n      }\n      AnnotationMirror typeAnnotation = Iterables.getOnlyElement(typeAnnotations);\n      assertThat(typeAnnotation.getAnnotationType().toString()).contains(\"Nullable\");\n    }\n  }\n\n  @Retention(RetentionPolicy.RUNTIME)\n  @Target(ElementType.TYPE_USE)\n  public @interface Nullable {}\n\n  @AutoValue\n  abstract static class NullableProperties {\n    abstract @Nullable String nullableString();\n\n    abstract int randomInt();\n\n    static NullableProperties create(@Nullable String nullableString, int randomInt) {\n      return new AutoValue_AutoValueJava8Test_NullableProperties(nullableString, randomInt);\n    }\n  }\n\n  @Test\n  public void testNullablePropertiesCanBeNull() {\n    NullableProperties instance = NullableProperties.create(null, 23);\n    assertThat(instance.nullableString()).isNull();\n    assertThat(instance.randomInt()).isEqualTo(23);\n    assertThat(instance.toString())\n        .isEqualTo(\"NullableProperties{nullableString=null, randomInt=23}\");\n  }\n\n  @Test\n  public void testEqualsParameterIsAnnotated() throws NoSuchMethodException {\n    // Sadly we can't rely on JDK 8 to handle type annotations correctly.\n    // Some versions do, some don't. So skip the test unless we are on at least JDK 9.\n    double javaVersion = Double.parseDouble(JAVA_SPECIFICATION_VERSION.value());\n    assume().that(javaVersion).isAtLeast(9.0);\n    NullableProperties nullableProperties = NullableProperties.create(null, 23);\n    Method equals = nullableProperties.getClass().getMethod(\"equals\", Object.class);\n    // If `java.lang.Object.equals` is itself annotated, for example with the JSpecify `@Nullable`,\n    // then we will copy that annotation onto the parameter of the generated `equals`\n    // implementation. Otherwise we will copy the `@Nullable` from the return type of the\n    // `nullableString()` method. So we accept either @Nullable here.\n    // (You might think we could just reflect on Object.equals to see if it has @Nullable, but in\n    // some environments we have nullness annotations at compile time but not at run time.)\n    assertThat(equals.getAnnotatedParameterTypes()[0].getAnnotations())\n        .asList()\n        .containsAnyIn(nullables(nullableProperties.getClass()));\n  }\n\n  @AutoAnnotation\n  static Nullable nullable() {\n    return new AutoAnnotation_AutoValueJava8Test_nullable();\n  }\n\n  /**\n   * Returns a set containing this test's {@link Nullable @Nullable} annotation, plus possibly\n   * another {@code @Nullable} that is present on the parameter of {@link Object#equals}.\n   */\n  static ImmutableSet<Annotation> nullables(Class<?> autoValueImplClass) {\n    try {\n      return Stream.concat(\n              Stream.of(nullable()),\n              stream(\n                      autoValueImplClass\n                          .getMethod(\"equals\", Object.class)\n                          .getAnnotatedParameterTypes()[0]\n                          .getAnnotations())\n                  .filter(a -> a.annotationType().getSimpleName().equals(\"Nullable\")))\n          .collect(toImmutableSet());\n    } catch (ReflectiveOperationException e) {\n      throw new LinkageError(e.getMessage(), e);\n    }\n  }\n\n  @Test\n  public void testNullablePropertyImplementationIsNullable() throws NoSuchMethodException {\n    Method method =\n        AutoValue_AutoValueJava8Test_NullableProperties.class.getDeclaredMethod(\"nullableString\");\n    assertThat(method.getAnnotatedReturnType().getAnnotations()).asList().contains(nullable());\n  }\n\n  @Test\n  public void testNullablePropertyConstructorParameterIsNullable() throws NoSuchMethodException {\n    Constructor<?> constructor =\n        AutoValue_AutoValueJava8Test_NullableProperties.class.getDeclaredConstructor(\n            String.class, int.class);\n    try {\n      assertThat(constructor.getAnnotatedParameterTypes()[0].getAnnotations())\n          .asList()\n          .contains(nullable());\n    } catch (AssertionError e) {\n      if (javacHandlesTypeAnnotationsCorrectly) {\n        throw e;\n      }\n    }\n  }\n\n  @AutoValue\n  abstract static class NullablePropertiesNotCopied {\n    @AutoValue.CopyAnnotations(exclude = Nullable.class)\n    abstract @Nullable String nullableString();\n\n    abstract int randomInt();\n\n    NullablePropertiesNotCopied create(String notNullableAfterAll, int randomInt) {\n      return new AutoValue_AutoValueJava8Test_NullablePropertiesNotCopied(\n          notNullableAfterAll, randomInt);\n    }\n  }\n\n  @Test\n  public void testExcludedNullablePropertyImplementation() throws NoSuchMethodException {\n    Method method =\n        AutoValue_AutoValueJava8Test_NullablePropertiesNotCopied.class.getDeclaredMethod(\n            \"nullableString\");\n    assertThat(method.getAnnotatedReturnType().getAnnotations())\n        .asList()\n        .doesNotContain(nullable());\n  }\n\n  @Test\n  public void testExcludedNullablePropertyConstructorParameter() throws NoSuchMethodException {\n    Constructor<?> constructor =\n        AutoValue_AutoValueJava8Test_NullablePropertiesNotCopied.class.getDeclaredConstructor(\n            String.class, int.class);\n    try {\n      assertThat(constructor.getAnnotatedParameterTypes()[0].getAnnotations())\n          .asList()\n          .doesNotContain(nullable());\n    } catch (AssertionError e) {\n      if (javacHandlesTypeAnnotationsCorrectly) {\n        throw e;\n      }\n    }\n  }\n\n  @AutoValue\n  abstract static class NullableNonNullable {\n    abstract @Nullable String nullableString();\n\n    abstract @Nullable String otherNullableString();\n\n    abstract String nonNullableString();\n\n    static NullableNonNullable create(\n        String nullableString, String otherNullableString, String nonNullableString) {\n      return new AutoValue_AutoValueJava8Test_NullableNonNullable(\n          nullableString, otherNullableString, nonNullableString);\n    }\n  }\n\n  @Test\n  public void testEqualsWithNullable() throws Exception {\n    NullableNonNullable everythingNull =\n        NullableNonNullable.create(null, null, \"nonNullableString\");\n    NullableNonNullable somethingNull =\n        NullableNonNullable.create(null, \"otherNullableString\", \"nonNullableString\");\n    NullableNonNullable nothingNull =\n        NullableNonNullable.create(\"nullableString\", \"otherNullableString\", \"nonNullableString\");\n    NullableNonNullable nothingNullAgain =\n        NullableNonNullable.create(\"nullableString\", \"otherNullableString\", \"nonNullableString\");\n    new EqualsTester()\n        .addEqualityGroup(everythingNull)\n        .addEqualityGroup(somethingNull)\n        .addEqualityGroup(nothingNull, nothingNullAgain)\n        .testEquals();\n  }\n\n  interface GenericGrandparent<T> {\n    T thing();\n  }\n\n  interface GenericParent<T> extends GenericGrandparent<T> {\n    @Override\n    @Nullable\n    T thing();\n  }\n\n  @AutoValue\n  abstract static class StringThing implements GenericParent<String> {}\n\n  @AutoValue\n  abstract static class StringThingWithBuilder implements GenericParent<String> {\n    static Builder builder() {\n      return new AutoValue_AutoValueJava8Test_StringThingWithBuilder.Builder();\n    }\n\n    @AutoValue.Builder\n    interface Builder {\n      Builder setThing(String thing);\n\n      @Nullable\n      String thing();\n\n      StringThingWithBuilder build();\n    }\n  }\n\n  @Test\n  public void testInheritedGetterRemainsNullable() throws NoSuchMethodException {\n    // Ensure that the implementation has `@Nullable String thing()`.\n    StringThing instance = new AutoValue_AutoValueJava8Test_StringThing(null);\n    Method getter = instance.getClass().getDeclaredMethod(\"thing\");\n    assertThat(getter.getAnnotatedReturnType().getAnnotations()).asList().contains(nullable());\n  }\n\n  @Test\n  public void testInheritedBuilderGetterRemainsNullable() throws NoSuchMethodException {\n    StringThingWithBuilder instance = StringThingWithBuilder.builder().setThing(null).build();\n    Method getter = instance.getClass().getDeclaredMethod(\"thing\");\n    assertThat(getter.getAnnotatedReturnType().getAnnotations()).asList().contains(nullable());\n  }\n\n  interface GenericListParent<T> {\n    List<@Nullable T> things();\n  }\n\n  @AutoValue\n  abstract static class StringList implements GenericListParent<String> {}\n\n  // We'd like AutoValue to realize that the effective type of `things()` in `StringList` is\n  // `List<@Nullable String>`. Unfortunately it doesn't, because Types.asMemberOf deletes\n  // annotations. The workaround that we have to restore them only works for top-level annotations,\n  // like the `@Nullable T` in `GenericParent`, but not like the `List<@Nullable T>` here.\n  @Test\n  public void testInheritedListGetterRemainsNullable() throws NoSuchMethodException {\n    StringList instance = new AutoValue_AutoValueJava8Test_StringList(ImmutableList.of());\n    Method getter = instance.getClass().getDeclaredMethod(\"things\");\n    AnnotatedParameterizedType returnType =\n        (AnnotatedParameterizedType) getter.getAnnotatedReturnType();\n    assertThat(returnType.getAnnotatedActualTypeArguments()[0].getAnnotations())\n        .asList()\n        .doesNotContain(nullable());\n    // This should be .contains(nullable()).\n  }\n\n  public static class Nested {}\n\n  @Retention(RetentionPolicy.RUNTIME)\n  @Target(ElementType.TYPE_USE)\n  public @interface OtherTypeAnnotation {}\n\n  @AutoAnnotation\n  public static OtherTypeAnnotation otherTypeAnnotation() {\n    return new AutoAnnotation_AutoValueJava8Test_otherTypeAnnotation();\n  }\n\n  @AutoValue\n  abstract static class NestedNullableProperties {\n    abstract @Nullable @OtherTypeAnnotation Nested nullableThing();\n\n    abstract int randomInt();\n\n    static Builder builder() {\n      return new AutoValue_AutoValueJava8Test_NestedNullableProperties.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder {\n      abstract Builder setNullableThing(@Nullable @OtherTypeAnnotation Nested thing);\n\n      abstract Builder setRandomInt(int x);\n\n      abstract NestedNullableProperties build();\n    }\n  }\n\n  @Test\n  public void testNestedNullablePropertiesCanBeNull() {\n    NestedNullableProperties instance = NestedNullableProperties.builder().setRandomInt(23).build();\n    assertThat(instance.nullableThing()).isNull();\n    assertThat(instance.randomInt()).isEqualTo(23);\n    assertThat(instance.toString())\n        .isEqualTo(\"NestedNullableProperties{nullableThing=null, randomInt=23}\");\n  }\n\n  @Test\n  public void testNestedNullablePropertiesAreCopied() throws Exception {\n    try {\n      Method generatedGetter =\n          AutoValue_AutoValueJava8Test_NestedNullableProperties.class.getDeclaredMethod(\n              \"nullableThing\");\n      Annotation[] getterAnnotations = generatedGetter.getAnnotatedReturnType().getAnnotations();\n      assertThat(getterAnnotations).asList().containsAtLeast(nullable(), otherTypeAnnotation());\n\n      Method generatedSetter =\n          AutoValue_AutoValueJava8Test_NestedNullableProperties.Builder.class.getDeclaredMethod(\n              \"setNullableThing\", Nested.class);\n      Annotation[] setterAnnotations =\n          generatedSetter.getAnnotatedParameterTypes()[0].getAnnotations();\n      assertThat(setterAnnotations).asList().containsAtLeast(nullable(), otherTypeAnnotation());\n    } catch (AssertionError e) {\n      if (javacHandlesTypeAnnotationsCorrectly) {\n        throw e;\n      }\n    }\n  }\n\n  @AutoValue\n  @SuppressWarnings(\"AutoValueImmutableFields\")\n  abstract static class PrimitiveArrays {\n    @SuppressWarnings(\"mutable\")\n    abstract boolean[] booleans();\n\n    @SuppressWarnings(\"mutable\")\n    abstract int @Nullable [] ints();\n\n    static PrimitiveArrays create(boolean[] booleans, int[] ints) {\n      // Real code would likely clone these parameters, but here we want to check that the\n      // generated constructor rejects a null value for booleans.\n      return new AutoValue_AutoValueJava8Test_PrimitiveArrays(booleans, ints);\n    }\n  }\n\n  @Test\n  public void testPrimitiveArrays() {\n    PrimitiveArrays object0 = PrimitiveArrays.create(new boolean[0], new int[0]);\n    boolean[] booleans = {false, true, true, false};\n    int[] ints = {6, 28, 496, 8128, 33550336};\n    PrimitiveArrays object1 = PrimitiveArrays.create(booleans.clone(), ints.clone());\n    PrimitiveArrays object2 = PrimitiveArrays.create(booleans.clone(), ints.clone());\n    new EqualsTester().addEqualityGroup(object1, object2).addEqualityGroup(object0).testEquals();\n    // EqualsTester also exercises hashCode(). We clone the arrays above to ensure that using the\n    // default Object.hashCode() will fail.\n\n    String expectedString =\n        \"PrimitiveArrays{booleans=\"\n            + Arrays.toString(booleans)\n            + \", \"\n            + \"ints=\"\n            + Arrays.toString(ints)\n            + \"}\";\n    assertThat(object1.toString()).isEqualTo(expectedString);\n\n    assertThat(object1.ints()).isSameInstanceAs(object1.ints());\n  }\n\n  @Test\n  public void testNullablePrimitiveArrays() {\n    assumeTrue(javacHandlesTypeAnnotationsCorrectly);\n    PrimitiveArrays object0 = PrimitiveArrays.create(new boolean[0], null);\n    boolean[] booleans = {false, true, true, false};\n    PrimitiveArrays object1 = PrimitiveArrays.create(booleans.clone(), null);\n    PrimitiveArrays object2 = PrimitiveArrays.create(booleans.clone(), null);\n    new EqualsTester().addEqualityGroup(object1, object2).addEqualityGroup(object0).testEquals();\n\n    String expectedString =\n        \"PrimitiveArrays{booleans=\" + Arrays.toString(booleans) + \", \" + \"ints=null}\";\n    assertThat(object1.toString()).isEqualTo(expectedString);\n\n    assertThat(object1.booleans()).isSameInstanceAs(object1.booleans());\n    assertThat(object1.booleans()).isEqualTo(booleans);\n    object1.booleans()[0] ^= true;\n    assertThat(object1.booleans()).isNotEqualTo(booleans);\n  }\n\n  @Test\n  public void testNotNullablePrimitiveArrays() {\n    NullPointerException e =\n        assertThrows(NullPointerException.class, () -> PrimitiveArrays.create(null, new int[0]));\n    assertThat(e).hasMessageThat().contains(\"booleans\");\n  }\n\n  @AutoValue\n  public abstract static class NullablePropertyWithBuilder {\n    public abstract String notNullable();\n\n    public abstract @Nullable String nullable();\n\n    public static Builder builder() {\n      return new AutoValue_AutoValueJava8Test_NullablePropertyWithBuilder.Builder();\n    }\n\n    @AutoValue.Builder\n    public interface Builder {\n      Builder notNullable(String s);\n\n      Builder nullable(@Nullable String s);\n\n      Optional<String> nullable();\n\n      NullablePropertyWithBuilder build();\n    }\n  }\n\n  @Test\n  public void testOmitNullableWithBuilder() {\n    NullablePropertyWithBuilder instance1 =\n        NullablePropertyWithBuilder.builder().notNullable(\"hello\").build();\n    assertThat(instance1.notNullable()).isEqualTo(\"hello\");\n    assertThat(instance1.nullable()).isNull();\n\n    NullablePropertyWithBuilder instance2 =\n        NullablePropertyWithBuilder.builder().notNullable(\"hello\").nullable(null).build();\n    assertThat(instance2.notNullable()).isEqualTo(\"hello\");\n    assertThat(instance2.nullable()).isNull();\n    assertThat(instance1).isEqualTo(instance2);\n\n    NullablePropertyWithBuilder instance3 =\n        NullablePropertyWithBuilder.builder().notNullable(\"hello\").nullable(\"world\").build();\n    assertThat(instance3.notNullable()).isEqualTo(\"hello\");\n    assertThat(instance3.nullable()).isEqualTo(\"world\");\n\n    IllegalStateException e =\n        assertThrows(\n            IllegalStateException.class, () -> NullablePropertyWithBuilder.builder().build());\n    assertThat(e).hasMessageThat().contains(\"notNullable\");\n\n    NullablePropertyWithBuilder.Builder builder = NullablePropertyWithBuilder.builder();\n    Truth.assertThat(builder.nullable()).isEmpty();\n  }\n\n  @AutoValue\n  public abstract static class OptionalPropertyWithNullableBuilder {\n    public abstract String notOptional();\n\n    public abstract Optional<String> optional();\n\n    public static Builder builder() {\n      return new AutoValue_AutoValueJava8Test_OptionalPropertyWithNullableBuilder.Builder();\n    }\n\n    @AutoValue.Builder\n    public interface Builder {\n      Builder notOptional(String s);\n\n      Builder optional(@Nullable String s);\n\n      OptionalPropertyWithNullableBuilder build();\n    }\n  }\n\n  @Test\n  public void testOmitOptionalWithNullableBuilder() {\n    OptionalPropertyWithNullableBuilder instance1 =\n        OptionalPropertyWithNullableBuilder.builder().notOptional(\"hello\").build();\n    assertThat(instance1.notOptional()).isEqualTo(\"hello\");\n    Truth.assertThat(instance1.optional()).isEmpty();\n\n    OptionalPropertyWithNullableBuilder instance2 =\n        OptionalPropertyWithNullableBuilder.builder().notOptional(\"hello\").optional(null).build();\n    assertThat(instance2.notOptional()).isEqualTo(\"hello\");\n    Truth.assertThat(instance2.optional()).isEmpty();\n    assertThat(instance1).isEqualTo(instance2);\n\n    OptionalPropertyWithNullableBuilder instance3 =\n        OptionalPropertyWithNullableBuilder.builder()\n            .notOptional(\"hello\")\n            .optional(\"world\")\n            .build();\n    assertThat(instance3.notOptional()).isEqualTo(\"hello\");\n    Truth.assertThat(instance3.optional()).hasValue(\"world\");\n\n    assertThrows(\n        IllegalStateException.class, () -> OptionalPropertyWithNullableBuilder.builder().build());\n  }\n\n  @AutoValue\n  public abstract static class NullableOptionalPropertyWithNullableBuilder {\n    public abstract @Nullable Optional<String> optional();\n\n    public static Builder builder() {\n      return new AutoValue_AutoValueJava8Test_NullableOptionalPropertyWithNullableBuilder.Builder();\n    }\n\n    @AutoValue.Builder\n    public interface Builder {\n      Builder optional(@Nullable String s);\n\n      Optional<String> optional();\n\n      NullableOptionalPropertyWithNullableBuilder build();\n    }\n  }\n\n  @Test\n  public void testNullableOptional() {\n    NullableOptionalPropertyWithNullableBuilder instance1 =\n        NullableOptionalPropertyWithNullableBuilder.builder().build();\n    Truth.assertThat(instance1.optional()).isNull();\n\n    NullableOptionalPropertyWithNullableBuilder instance2 =\n        NullableOptionalPropertyWithNullableBuilder.builder().optional(null).build();\n    Truth.assertThat(instance2.optional()).isEmpty();\n\n    NullableOptionalPropertyWithNullableBuilder instance3 =\n        NullableOptionalPropertyWithNullableBuilder.builder().optional(\"haruspex\").build();\n    Truth.assertThat(instance3.optional()).hasValue(\"haruspex\");\n\n    NullableOptionalPropertyWithNullableBuilder.Builder builder =\n        NullableOptionalPropertyWithNullableBuilder.builder();\n    Truth.assertThat(builder.optional()).isNull();\n  }\n\n  @AutoValue\n  @SuppressWarnings(\"AutoValueImmutableFields\")\n  public abstract static class BuilderWithUnprefixedGetters<T extends Comparable<T>> {\n    public abstract ImmutableList<T> list();\n\n    public abstract @Nullable T t();\n\n    @SuppressWarnings(\"mutable\")\n    public abstract int[] ints();\n\n    public abstract int noGetter();\n\n    public static <T extends Comparable<T>> Builder<T> builder() {\n      return new AutoValue_AutoValueJava8Test_BuilderWithUnprefixedGetters.Builder<T>();\n    }\n\n    @AutoValue.Builder\n    public interface Builder<T extends Comparable<T>> {\n      Builder<T> setList(ImmutableList<T> list);\n\n      Builder<T> setT(T t);\n\n      Builder<T> setInts(int[] ints);\n\n      Builder<T> setNoGetter(int x);\n\n      ImmutableList<T> list();\n\n      T t();\n\n      int[] ints();\n\n      BuilderWithUnprefixedGetters<T> build();\n    }\n  }\n\n  @AutoValue\n  abstract static class NoNullableRef {\n    abstract String foo();\n\n    static NoNullableRef of(String foo) {\n      return new AutoValue_AutoValueJava8Test_NoNullableRef(foo);\n    }\n  }\n\n  // Tests that we generate equals(@Nullable x) using JSpecify @Nullable if that annotation is\n  // available and there is no other @Nullable type annotation mentioned in the @AutoValue class.\n  // If there *are* other @Nullable type annotations, other test methods here will check that they\n  // are used instead.\n  @Test\n  public void testDefaultToJSpecifyNullable() throws ReflectiveOperationException {\n    Class<? extends Annotation> jspecifyNullable;\n    try {\n      // We write this using .concat in order to hide it from rewriting rules.\n      jspecifyNullable =\n          Class.forName(\"org\".concat(\".jspecify.annotations.Nullable\"))\n              .asSubclass(Annotation.class);\n    } catch (ClassNotFoundException e) {\n      throw new AssumptionViolatedException(\"No JSpecify @Nullable available\", e);\n    }\n    Class<? extends NoNullableRef> autoValueImpl = NoNullableRef.of(\"foo\").getClass();\n    Method equals = autoValueImpl.getDeclaredMethod(\"equals\", Object.class);\n    assertThat(equals.getAnnotatedParameterTypes()[0].isAnnotationPresent(jspecifyNullable))\n        .isTrue();\n  }\n\n  @Test\n  public void testBuilderWithUnprefixedGetter() {\n    assumeTrue(javacHandlesTypeAnnotationsCorrectly);\n    ImmutableList<String> names = ImmutableList.of(\"fred\", \"jim\");\n    int[] ints = {6, 28, 496, 8128, 33550336};\n    int noGetter = -1;\n\n    BuilderWithUnprefixedGetters.Builder<String> builder = BuilderWithUnprefixedGetters.builder();\n    assertThat(builder.t()).isNull();\n    IllegalStateException e1 = assertThrows(IllegalStateException.class, () -> builder.list());\n    assertThat(e1).hasMessageThat().isEqualTo(\"Property \\\"list\\\" has not been set\");\n    IllegalStateException e2 = assertThrows(IllegalStateException.class, () -> builder.ints());\n    assertThat(e2).hasMessageThat().isEqualTo(\"Property \\\"ints\\\" has not been set\");\n\n    builder.setList(names);\n    assertThat(builder.list()).isSameInstanceAs(names);\n    builder.setInts(ints);\n    assertThat(builder.ints()).isEqualTo(ints);\n    // The array is not cloned by the getter, so the client can modify it (but shouldn't).\n    ints[0] = 0;\n    assertThat(builder.ints()[0]).isEqualTo(0);\n    ints[0] = 6;\n\n    BuilderWithUnprefixedGetters<String> instance = builder.setNoGetter(noGetter).build();\n    assertThat(instance.list()).isSameInstanceAs(names);\n    assertThat(instance.t()).isNull();\n    assertThat(instance.ints()).isEqualTo(ints);\n    assertThat(instance.noGetter()).isEqualTo(noGetter);\n  }\n\n  @AutoValue\n  @SuppressWarnings(\"AutoValueImmutableFields\")\n  public abstract static class BuilderWithPrefixedGetters<T extends Comparable<T>> {\n    public abstract ImmutableList<T> getList();\n\n    public abstract @Nullable T getT();\n\n    @SuppressWarnings(\"mutable\")\n    public abstract int @Nullable [] getInts();\n\n    public abstract int getNoGetter();\n\n    public static <T extends Comparable<T>> Builder<T> builder() {\n      return new AutoValue_AutoValueJava8Test_BuilderWithPrefixedGetters.Builder<T>();\n    }\n\n    @AutoValue.Builder\n    public abstract static class Builder<T extends Comparable<T>> {\n      public abstract Builder<T> setList(ImmutableList<T> list);\n\n      public abstract Builder<T> setT(@Nullable T t);\n\n      public abstract Builder<T> setInts(int[] ints);\n\n      public abstract Builder<T> setNoGetter(int x);\n\n      abstract ImmutableList<T> getList();\n\n      abstract T getT();\n\n      abstract int[] getInts();\n\n      public abstract BuilderWithPrefixedGetters<T> build();\n    }\n  }\n\n  @Test\n  public void testBuilderWithPrefixedGetter() {\n    assumeTrue(javacHandlesTypeAnnotationsCorrectly);\n    ImmutableList<String> names = ImmutableList.of(\"fred\", \"jim\");\n    String name = \"sheila\";\n    int noGetter = -1;\n\n    BuilderWithPrefixedGetters.Builder<String> builder = BuilderWithPrefixedGetters.builder();\n    assertThat(builder.getInts()).isNull();\n    IllegalStateException e = assertThrows(IllegalStateException.class, () -> builder.getList());\n    assertThat(e).hasMessageThat().isEqualTo(\"Property \\\"list\\\" has not been set\");\n\n    builder.setList(names);\n    assertThat(builder.getList()).isSameInstanceAs(names);\n    builder.setT(name);\n    assertThat(builder.getInts()).isNull();\n\n    BuilderWithPrefixedGetters<String> instance = builder.setNoGetter(noGetter).build();\n    assertThat(instance.getList()).isSameInstanceAs(names);\n    assertThat(instance.getT()).isEqualTo(name);\n    assertThat(instance.getInts()).isNull();\n    assertThat(instance.getNoGetter()).isEqualTo(noGetter);\n  }\n\n  // This class tests the case where an annotation is both a method annotation and a type\n  // annotation. If we weren't careful, we might emit it twice in the generated code.\n  @AutoValue\n  abstract static class FunkyNullable {\n    @Target({ElementType.METHOD, ElementType.TYPE_USE})\n    @interface Nullable {}\n\n    abstract @Nullable String foo();\n\n    abstract Optional<String> bar();\n\n    static Builder builder() {\n      return new AutoValue_AutoValueJava8Test_FunkyNullable.Builder();\n    }\n\n    @AutoValue.Builder\n    interface Builder {\n      Builder setFoo(@Nullable String foo);\n\n      Builder setBar(@Nullable String bar);\n\n      FunkyNullable build();\n    }\n  }\n\n  @Test\n  public void testFunkyNullable() {\n    FunkyNullable explicitNull = FunkyNullable.builder().setFoo(null).setBar(null).build();\n    FunkyNullable implicitNull = FunkyNullable.builder().build();\n    assertThat(explicitNull).isEqualTo(implicitNull);\n  }\n\n  @AutoValue\n  abstract static class EqualsNullable {\n    @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})\n    @Retention(RetentionPolicy.RUNTIME)\n    @interface Nullable {}\n\n    abstract String foo();\n\n    static EqualsNullable create(String foo) {\n      return new AutoValue_AutoValueJava8Test_EqualsNullable(foo);\n    }\n\n    @Override\n    public abstract boolean equals(@Nullable Object x);\n\n    @Override\n    public abstract int hashCode();\n  }\n\n  /**\n   * Tests that a type annotation on the parameter of {@code equals(Object)} is copied into the\n   * implementation class.\n   */\n  @Test\n  public void testEqualsNullable() throws ReflectiveOperationException {\n    EqualsNullable x = EqualsNullable.create(\"foo\");\n    Class<? extends EqualsNullable> implClass = x.getClass();\n    Method equals = implClass.getDeclaredMethod(\"equals\", Object.class);\n    AnnotatedType[] parameterTypes = equals.getAnnotatedParameterTypes();\n    assertThat(parameterTypes[0].isAnnotationPresent(EqualsNullable.Nullable.class)).isTrue();\n  }\n\n  @AutoValue\n  abstract static class AnnotatedTypeParameter<@Nullable T> {\n    abstract @Nullable T thing();\n\n    static <@Nullable T> AnnotatedTypeParameter<T> create(T thing) {\n      return new AutoValue_AutoValueJava8Test_AnnotatedTypeParameter<T>(thing);\n    }\n  }\n\n  /**\n   * Tests that an annotation on a type parameter of an {@code @AutoValue} class is copied to the\n   * implementation class.\n   */\n  @Test\n  public void testTypeAnnotationCopiedToImplementation() {\n    @Nullable String nullableString = \"blibby\";\n    AnnotatedTypeParameter<@Nullable String> x = AnnotatedTypeParameter.create(nullableString);\n    Class<?> c = x.getClass();\n    assertThat(c.getTypeParameters()).hasLength(1);\n    TypeVariable<?> typeParameter = c.getTypeParameters()[0];\n    assertWithMessage(typeParameter.toString())\n        .that(typeParameter.getAnnotations())\n        .asList()\n        .contains(nullable());\n  }\n\n  @AutoValue\n  abstract static class AnnotatedTypeParameterWithBuilder<@Nullable T> {\n    abstract @Nullable T thing();\n\n    static <@Nullable T> Builder<T> builder() {\n      return new AutoValue_AutoValueJava8Test_AnnotatedTypeParameterWithBuilder.Builder<T>();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder<@Nullable T> {\n      abstract Builder<T> setThing(T thing);\n\n      abstract AnnotatedTypeParameterWithBuilder<T> build();\n    }\n  }\n\n  /**\n   * Tests that an annotation on a type parameter of an {@code @AutoValue} builder is copied to the\n   * implementation class.\n   */\n  @Test\n  public void testTypeAnnotationOnBuilderCopiedToImplementation() {\n    AnnotatedTypeParameterWithBuilder.Builder<@Nullable String> builder =\n        AnnotatedTypeParameterWithBuilder.builder();\n    Class<?> c = builder.getClass();\n    assertThat(c.getTypeParameters()).hasLength(1);\n    TypeVariable<?> typeParameter = c.getTypeParameters()[0];\n    assertWithMessage(typeParameter.toString())\n        .that(typeParameter.getAnnotations())\n        .asList()\n        .contains(nullable());\n  }\n\n  // b/127701294\n  @AutoValue\n  abstract static class OptionalOptional {\n    abstract Optional<Optional<String>> maybeJustMaybe();\n\n    static Builder builder() {\n      return new AutoValue_AutoValueJava8Test_OptionalOptional.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder {\n      abstract Builder maybeJustMaybe(Optional<String> maybe);\n\n      abstract OptionalOptional build();\n    }\n  }\n\n  @Test\n  public void testOptionalOptional_empty() {\n    OptionalOptional empty = OptionalOptional.builder().build();\n    Truth.assertThat(empty.maybeJustMaybe()).isEmpty();\n  }\n\n  @Test\n  public void testOptionalOptional_ofEmpty() {\n    OptionalOptional ofEmpty = OptionalOptional.builder().maybeJustMaybe(Optional.empty()).build();\n    Truth.assertThat(ofEmpty.maybeJustMaybe()).hasValue(Optional.empty());\n  }\n\n  @Test\n  public void testOptionalOptional_ofSomething() {\n    OptionalOptional ofSomething =\n        OptionalOptional.builder().maybeJustMaybe(Optional.of(\"foo\")).build();\n    Truth.assertThat(ofSomething.maybeJustMaybe()).hasValue(Optional.of(\"foo\"));\n  }\n\n  @AutoValue\n  abstract static class OptionalExtends {\n    abstract Optional<? extends Predicate<? super Integer>> predicate();\n\n    static Builder builder() {\n      return new AutoValue_AutoValueJava8Test_OptionalExtends.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder {\n      abstract Builder setPredicate(Predicate<? super Integer> predicate);\n\n      abstract OptionalExtends build();\n    }\n  }\n\n  @Test\n  public void testOptionalExtends() {\n    Predicate<Number> predicate = n -> n.toString().equals(\"0\");\n    OptionalExtends t = OptionalExtends.builder().setPredicate(predicate).build();\n    Truth.assertThat(t.predicate()).hasValue(predicate);\n  }\n\n  @AutoValue\n  public abstract static class Foo {\n    public abstract Bar bar();\n\n    public abstract double baz();\n\n    public static Foo.Builder builder() {\n      return new AutoValue_AutoValueJava8Test_Foo.Builder();\n    }\n\n    @AutoValue.Builder\n    public abstract static class Builder {\n      // https://github.com/google/auto/blob/main/value/userguide/builders-howto.md#normalize\n      abstract Optional<Bar> bar();\n\n      public abstract Builder bar(Bar bar);\n\n      // https://github.com/google/auto/blob/main/value/userguide/builders-howto.md#nested_builders\n      public abstract Bar.Builder barBuilder();\n\n      abstract OptionalDouble baz();\n\n      public abstract Builder baz(double baz);\n\n      abstract Foo autoBuild();\n\n      public Foo build() {\n        if (!bar().isPresent()) {\n          bar(Bar.builder().build());\n        }\n        if (!baz().isPresent()) {\n          baz(0.0);\n        }\n        return autoBuild();\n      }\n    }\n  }\n\n  @AutoValue\n  public abstract static class Bar {\n    public abstract Bar.Builder toBuilder();\n\n    public static Bar.Builder builder() {\n      return new AutoValue_AutoValueJava8Test_Bar.Builder();\n    }\n\n    @AutoValue.Builder\n    public abstract static class Builder {\n      public abstract Bar build();\n    }\n  }\n\n  @Test\n  public void nestedOptionalGetter() {\n    Foo foo = Foo.builder().build();\n    assertThat(foo.bar()).isNotNull();\n    assertThat(foo.baz()).isEqualTo(0.0);\n  }\n\n  // Test that we can build a property of type List<? extends Foo> using a property builder whose\n  // build() method returns List<Foo>. The main motivation for this is Kotlin, where you can\n  // easily run into this situation with \"in\" types.\n  // This is a \"Java 8\" test because the generated code uses List.of (which is actually Java 9).\n  // If we really are on Java 8 then the generated code will use `new ListBuilder<T>().build()`\n  // instead.\n  @AutoValue\n  public abstract static class PropertyBuilderWildcard<T> {\n    public abstract List<? extends T> list();\n\n    public static <T> PropertyBuilderWildcard.Builder<T> builder() {\n      return new AutoValue_AutoValueJava8Test_PropertyBuilderWildcard.Builder<>();\n    }\n\n    @AutoValue.Builder\n    public interface Builder<T> {\n      ListBuilder<T> listBuilder();\n\n      PropertyBuilderWildcard<T> build();\n    }\n\n    public static class ListBuilder<T> {\n      private final List<T> list = new ArrayList<>();\n\n      public void add(T value) {\n        list.add(value);\n      }\n\n      public List<T> build() {\n        return list;\n      }\n    }\n  }\n\n  @Test\n  public void propertyBuilderWildcard() {\n    PropertyBuilderWildcard.Builder<CharSequence> builder = PropertyBuilderWildcard.builder();\n    builder.listBuilder().add(\"foo\");\n    assertThat(builder.build().list()).containsExactly(\"foo\");\n  }\n\n  @AutoValue\n  public abstract static class NullableBound<T extends @Nullable Object> {\n    public abstract T maybeNullable();\n\n    public static <T extends @Nullable Object> NullableBound<T> create(T maybeNullable) {\n      return new AutoValue_AutoValueJava8Test_NullableBound<>(maybeNullable);\n    }\n  }\n\n  @Test\n  public void propertyCanBeNullIfNullableBound() {\n    assumeTrue(javacHandlesTypeAnnotationsCorrectly);\n    // The generated class doesn't know what the actual type argument is, so it can't know whether\n    // it is @Nullable. Because of the @Nullable bound, it omits an explicit null check, under the\n    // assumption that some static-checking framework is validating type uses.\n    NullableBound<@Nullable String> x = NullableBound.create(null);\n    assertThat(x.maybeNullable()).isNull();\n  }\n\n  @AutoValue\n  public abstract static class NullableIntersectionBound<\n      T extends @Nullable Object & @Nullable Serializable> {\n    public abstract T maybeNullable();\n\n    public static <T extends @Nullable Object & @Nullable Serializable>\n        NullableIntersectionBound<T> create(T maybeNullable) {\n      return new AutoValue_AutoValueJava8Test_NullableIntersectionBound<>(maybeNullable);\n    }\n  }\n\n  @Test\n  public void propertyCanBeNullIfNullableIntersectionBound() {\n    assumeTrue(javacHandlesTypeAnnotationsCorrectly);\n    // The generated class doesn't know what the actual type argument is, so it can't know whether\n    // it is @Nullable. Because of the @Nullable bound, it omits an explicit null check, under the\n    // assumption that some static-checking framework is validating type uses.\n    NullableIntersectionBound<@Nullable String> x = NullableIntersectionBound.create(null);\n    assertThat(x.maybeNullable()).isNull();\n  }\n\n  @AutoValue\n  public abstract static class PartlyNullableIntersectionBound<\n      T extends @Nullable Object & Serializable> {\n    public abstract T notNullable();\n\n    public static <T extends @Nullable Object & Serializable>\n        PartlyNullableIntersectionBound<T> create(T notNullable) {\n      return new AutoValue_AutoValueJava8Test_PartlyNullableIntersectionBound<>(notNullable);\n    }\n  }\n\n  @Test\n  public void propertyCannotBeNullWithPartlyNullableIntersectionBound() {\n    assumeTrue(javacHandlesTypeAnnotationsCorrectly);\n    assertThrows(NullPointerException.class, () -> PartlyNullableIntersectionBound.create(null));\n  }\n\n  @AutoValue\n  public abstract static class NullableVariableBound<T extends @Nullable Object, U extends T> {\n    public abstract T nullOne();\n\n    public abstract U nullTwo();\n\n    public static <T extends @Nullable Object, U extends T> NullableVariableBound<T, U> create(\n        T nullOne, U nullTwo) {\n      return new AutoValue_AutoValueJava8Test_NullableVariableBound<>(nullOne, nullTwo);\n    }\n  }\n\n  @Test\n  public void nullableVariableBound() {\n    assumeTrue(javacHandlesTypeAnnotationsCorrectly);\n    NullableVariableBound<@Nullable CharSequence, @Nullable String> x =\n        NullableVariableBound.create(null, null);\n    assertThat(x.nullOne()).isNull();\n    assertThat(x.nullTwo()).isNull();\n  }\n\n  @AutoValue\n  public abstract static class NotNullableVariableBound<T> {\n    public abstract T t();\n\n    public abstract @Nullable T nullableT();\n\n    public abstract String string();\n\n    public static <T> Builder<T> builder() {\n      return new AutoValue_AutoValueJava8Test_NotNullableVariableBound.Builder<>();\n    }\n\n    @AutoValue.Builder\n    public abstract static class Builder<T> {\n      public abstract Builder<T> setT(T t);\n\n      public abstract Builder<T> setNullableT(@Nullable T nullableT);\n\n      public abstract Builder<T> setString(String string);\n\n      public abstract NotNullableVariableBound<T> build();\n    }\n  }\n\n  @Test\n  public void typeParameterBuilderFieldsAreNullable() throws ReflectiveOperationException {\n    assertThrows(NullPointerException.class, () -> NotNullableVariableBound.builder().setT(null));\n\n    // Even though neither t() nor string() has a @Nullable return type, the corresponding builder\n    // fields should be @Nullable. This test depends on the knowledge that for a property `t`, we\n    // will have a field also called `t`.\n    // For `nullableT`, the @Nullable in question should be the same as the one on the return type\n    // of nullableT(). For `t`, it is a @Nullable that AutoValue found somewhere, either there or\n    // possibly on the parameter of the inherited Object.equals method.\n    Field builderT = NotNullableVariableBound.builder().getClass().getDeclaredField(\"t\");\n    assertThat(builderT.getAnnotatedType().getAnnotations())\n        .asList()\n        .containsAnyIn(nullables(AutoValue_AutoValueJava8Test_NotNullableVariableBound.class));\n    Field builderNullableT =\n        NotNullableVariableBound.builder().getClass().getDeclaredField(\"nullableT\");\n    assertThat(builderNullableT.getAnnotatedType().getAnnotations()).asList().contains(nullable());\n\n    // Meanwhile the AutoValue class itself should have @Nullable on the private field, the getter\n    // method, and the constructor parameter for nullableT. This @Nullable should be the same as\n    // the one on the return type of nullableT().\n    Class<?> autoValueClass = AutoValue_AutoValueJava8Test_NotNullableVariableBound.class;\n    Field nullableTField = autoValueClass.getDeclaredField(\"nullableT\");\n    assertThat(nullableTField.getAnnotatedType().getAnnotations()).asList().contains(nullable());\n    Method nullableTMethod = autoValueClass.getMethod(\"nullableT\");\n    assertThat(nullableTMethod.getAnnotatedReturnType().getAnnotations())\n        .asList()\n        .contains(nullable());\n    Constructor<?> autoValueConstructor =\n        autoValueClass.getDeclaredConstructor(Object.class, Object.class, String.class);\n    assertThat(autoValueConstructor.getAnnotatedParameterTypes()[1].getAnnotations())\n        .asList()\n        .contains(nullable());\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/AutoValueNotEclipseTest.java",
    "content": "/*\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value;\n\nimport static com.google.common.truth.Truth.assertThat;\n\nimport java.util.Optional;\nimport javax.annotation.Nullable;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * Like {@link AutoValueTest}, but with code that doesn't build with at least some versions of\n * Eclipse, and should therefore not be included in {@link CompileWithEclipseTest}. (The latter is\n * not currently present in the open-source build.)\n */\n@RunWith(JUnit4.class)\npublic class AutoValueNotEclipseTest {\n  // This produced the following error with JDT 4.6:\n  // Internal compiler error: java.lang.Exception: java.lang.IllegalArgumentException: element\n  // public abstract B setOptional(T)  is not a member of the containing type\n  // com.google.auto.value.AutoValueTest.ConcreteOptional.Builder nor any of its superclasses at\n  // org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatcher.handleProcessor(RoundDispatcher.java:169)\n  interface AbstractOptional<T> {\n    Optional<T> optional();\n\n    interface Builder<T, B extends Builder<T, B>> {\n      B setOptional(@Nullable T t);\n    }\n  }\n\n  @AutoValue\n  abstract static class ConcreteOptional implements AbstractOptional<String> {\n    static Builder builder() {\n      return new AutoValue_AutoValueNotEclipseTest_ConcreteOptional.Builder();\n    }\n\n    @AutoValue.Builder\n    interface Builder extends AbstractOptional.Builder<String, Builder> {\n      ConcreteOptional build();\n    }\n  }\n\n  @Test\n  public void genericOptionalOfNullable() {\n    ConcreteOptional empty = ConcreteOptional.builder().build();\n    assertThat(empty.optional()).isEmpty();\n    ConcreteOptional notEmpty = ConcreteOptional.builder().setOptional(\"foo\").build();\n    assertThat(notEmpty.optional()).hasValue(\"foo\");\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/AutoValueTest.java",
    "content": "/*\n * Copyright 2012 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.common.truth.Truth.assertWithMessage;\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertNotNull;\nimport static org.junit.Assert.assertNotSame;\nimport static org.junit.Assert.assertNull;\nimport static org.junit.Assert.assertSame;\nimport static org.junit.Assert.assertTrue;\nimport static org.junit.Assert.fail;\n\nimport com.google.common.base.MoreObjects;\nimport com.google.common.collect.ComparisonChain;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.ImmutableSortedMap;\nimport com.google.common.collect.ImmutableSortedSet;\nimport com.google.common.collect.ImmutableTable;\nimport com.google.common.collect.Ordering;\nimport com.google.common.testing.EqualsTester;\nimport com.google.common.testing.SerializableTester;\nimport java.io.ObjectStreamClass;\nimport java.io.Serializable;\nimport java.lang.annotation.Annotation;\nimport java.lang.annotation.Inherited;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Modifier;\nimport java.lang.reflect.Type;\nimport java.math.BigInteger;\nimport java.util.AbstractList;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.NavigableMap;\nimport java.util.NavigableSet;\nimport java.util.NoSuchElementException;\nimport java.util.SortedMap;\nimport java.util.SortedSet;\nimport java.util.TreeMap;\nimport java.util.TreeSet;\nimport javax.annotation.Nullable;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\n@SuppressWarnings({\n  \"AutoValueImmutableFields\",\n  \"AutoValueFinalMethods\",\n  \"TypeNameShadowing\",\n  \"SelfAssertion\"\n})\npublic class AutoValueTest {\n  private static boolean omitIdentifiers;\n\n  @BeforeClass\n  public static void initOmitIdentifiers() {\n    omitIdentifiers = System.getProperty(\"OmitIdentifiers\") != null;\n  }\n\n  @AutoValue\n  abstract static class Simple {\n    public abstract String publicString();\n\n    protected abstract int protectedInt();\n\n    abstract Map<String, Long> packageMap();\n\n    public static Simple create(String s, int i, Map<String, Long> m) {\n      return new AutoValue_AutoValueTest_Simple(s, i, m);\n    }\n  }\n\n  @Test\n  public void testSimple() throws Exception {\n    Simple instance1a = Simple.create(\"example\", 23, ImmutableMap.of(\"twenty-three\", 23L));\n    Simple instance1b = Simple.create(\"example\", 23, ImmutableMap.of(\"twenty-three\", 23L));\n    Simple instance2 = Simple.create(\"\", 0, ImmutableMap.<String, Long>of());\n    assertEquals(\"example\", instance1a.publicString());\n    assertEquals(23, instance1a.protectedInt());\n    assertEquals(ImmutableMap.of(\"twenty-three\", 23L), instance1a.packageMap());\n    MoreObjects.ToStringHelper toStringHelper = MoreObjects.toStringHelper(Simple.class);\n    toStringHelper.add(\"publicString\", \"example\");\n    toStringHelper.add(\"protectedInt\", 23);\n    toStringHelper.add(\"packageMap\", ImmutableMap.of(\"twenty-three\", 23L));\n    String expectedString =\n        omitIdentifiers ? \"{example, 23, {twenty-three=23}}\" : toStringHelper.toString();\n    assertThat(instance1a.toString()).isEqualTo(expectedString);\n    new EqualsTester()\n        .addEqualityGroup(instance1a, instance1b)\n        .addEqualityGroup(instance2)\n        .testEquals();\n  }\n\n  @AutoValue\n  abstract static class Empty {\n    public static Empty create() {\n      return new AutoValue_AutoValueTest_Empty();\n    }\n  }\n\n  @Test\n  public void testEmpty() throws Exception {\n    Empty instance = Empty.create();\n    String expectedString = omitIdentifiers ? \"{}\" : \"Empty{}\";\n    assertThat(instance.toString()).isEqualTo(expectedString);\n    assertEquals(instance, instance);\n    assertEquals(instance, Empty.create());\n  }\n\n  @AutoValue\n  abstract static class SimpleWithGetters {\n    abstract int getFoo();\n\n    abstract boolean isBar();\n\n    abstract boolean getOtherBar();\n\n    abstract String getPackage(); // package is a reserved word\n\n    abstract String getPackage0();\n\n    abstract String getHTMLPage();\n\n    static SimpleWithGetters create(\n        int foo, boolean bar, boolean otherBar, String pkg, String pkg0, String htmlPage) {\n      return new AutoValue_AutoValueTest_SimpleWithGetters(foo, bar, otherBar, pkg, pkg0, htmlPage);\n    }\n  }\n\n  @Test\n  public void testGetters() {\n    SimpleWithGetters instance = SimpleWithGetters.create(23, true, false, \"foo\", \"bar\", \"<html>\");\n    String expectedString =\n        omitIdentifiers\n            ? \"{23, true, false, foo, bar, <html>}\"\n            : \"SimpleWithGetters{\"\n                + \"foo=23, bar=true, otherBar=false, package=foo, package0=bar, HTMLPage=<html>}\";\n    assertThat(instance.toString()).isEqualTo(expectedString);\n  }\n\n  @AutoValue\n  abstract static class NotAllGetters {\n    abstract int getFoo();\n\n    abstract boolean bar();\n\n    static NotAllGetters create(int foo, boolean bar) {\n      return new AutoValue_AutoValueTest_NotAllGetters(foo, bar);\n    }\n  }\n\n  @Test\n  public void testNotGetters() {\n    NotAllGetters instance = NotAllGetters.create(23, true);\n    String expectedString = omitIdentifiers ? \"{23, true}\" : \"NotAllGetters{getFoo=23, bar=true}\";\n    assertThat(instance.toString()).isEqualTo(expectedString);\n  }\n\n  @AutoValue\n  abstract static class StrangeGetters {\n    abstract int get1st();\n\n    abstract int get_1st(); // by default we'll use _1st where identifiers are needed, so foil that.\n\n    @AutoValue.Builder\n    abstract static class Builder {\n      abstract Builder set1st(int x);\n\n      abstract Builder set_1st(int x);\n\n      abstract StrangeGetters build();\n    }\n\n    static Builder builder() {\n      return new AutoValue_AutoValueTest_StrangeGetters.Builder();\n    }\n  }\n\n  @Test\n  public void testStrangeGetters() {\n    StrangeGetters instance = StrangeGetters.builder().set1st(17).set_1st(23).build();\n    String expectedString = omitIdentifiers ? \"{17, 23}\" : \"StrangeGetters{1st=17, _1st=23}\";\n    assertThat(instance.toString()).isEqualTo(expectedString);\n  }\n\n  @AutoValue\n  abstract static class GettersAndConcreteNonGetters {\n    abstract int getFoo();\n\n    @SuppressWarnings(\"mutable\")\n    abstract byte[] getBytes();\n\n    boolean hasNoBytes() {\n      return getBytes().length == 0;\n    }\n\n    static GettersAndConcreteNonGetters create(int foo, byte[] bytes) {\n      return new AutoValue_AutoValueTest_GettersAndConcreteNonGetters(foo, bytes);\n    }\n  }\n\n  @Test\n  public void testGettersAndConcreteNonGetters() {\n    GettersAndConcreteNonGetters instance = GettersAndConcreteNonGetters.create(23, new byte[] {1});\n    assertFalse(instance.hasNoBytes());\n    String expectedString =\n        omitIdentifiers ? \"{23, [1]}\" : \"GettersAndConcreteNonGetters{foo=23, bytes=[1]}\";\n    assertThat(instance.toString()).isEqualTo(expectedString);\n  }\n\n  @AutoValue\n  abstract static class ClassProperty {\n    abstract Class<?> theClass();\n\n    static ClassProperty create(Class<?> theClass) {\n      return new AutoValue_AutoValueTest_ClassProperty(theClass);\n    }\n  }\n\n  @Test\n  public void testClassProperty() {\n    ClassProperty instance = ClassProperty.create(Thread.class);\n    assertThat(instance.theClass()).isEqualTo(Thread.class);\n\n    try {\n      ClassProperty.create(null);\n      fail();\n    } catch (NullPointerException expected) {\n    }\n  }\n\n  @AutoValue\n  abstract static class ClassPropertyWithBuilder {\n    abstract Class<? extends Number> numberClass();\n\n    static Builder builder() {\n      return new AutoValue_AutoValueTest_ClassPropertyWithBuilder.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder {\n      abstract Builder setNumberClass(Class<? extends Number> x);\n\n      abstract ClassPropertyWithBuilder build();\n    }\n  }\n\n  @Test\n  public void testClassPropertyWithBuilder() {\n    ClassPropertyWithBuilder instance =\n        ClassPropertyWithBuilder.builder().setNumberClass(Integer.class).build();\n    assertThat(instance.numberClass()).isEqualTo(Integer.class);\n\n    try {\n      ClassPropertyWithBuilder.builder().build();\n      fail();\n    } catch (IllegalStateException expected) {\n    }\n\n    try {\n      ClassPropertyWithBuilder.builder().setNumberClass(null);\n      fail();\n    } catch (NullPointerException expected) {\n    }\n  }\n\n  @AutoValue\n  public abstract static class Serialize implements Serializable {\n    private static final long serialVersionUID = 1L;\n\n    public abstract int integer();\n\n    public abstract String string();\n\n    public abstract BigInteger bigInteger();\n\n    public static Serialize create(int integer, String string, BigInteger bigInteger) {\n      return new AutoValue_AutoValueTest_Serialize(integer, string, bigInteger);\n    }\n  }\n\n  @Test\n  public void testSerialize() throws Exception {\n    Serialize instance = Serialize.create(23, \"23\", BigInteger.valueOf(23));\n    assertEquals(instance, SerializableTester.reserialize(instance));\n  }\n\n  @AutoValue\n  public abstract static class SerializeWithVersionUID implements Serializable {\n    private static final long serialVersionUID = 4294967297L;\n\n    public abstract int integer();\n\n    public abstract String string();\n\n    public static SerializeWithVersionUID create(int integer, String string) {\n      return new AutoValue_AutoValueTest_SerializeWithVersionUID(integer, string);\n    }\n  }\n\n  @Test\n  public void testSerializeWithVersionUID() throws Exception {\n    SerializeWithVersionUID instance = SerializeWithVersionUID.create(23, \"23\");\n    assertEquals(instance, SerializableTester.reserialize(instance));\n\n    long serialVersionUID =\n        ObjectStreamClass.lookup(AutoValue_AutoValueTest_SerializeWithVersionUID.class)\n            .getSerialVersionUID();\n    assertEquals(4294967297L, serialVersionUID);\n  }\n\n  @AutoValue\n  abstract static class LongProperty {\n    public abstract long longProperty();\n\n    public static LongProperty create(long longProperty) {\n      return new AutoValue_AutoValueTest_LongProperty(longProperty);\n    }\n  }\n\n  @Test\n  public void testLongHashCode() {\n    long longValue = 0x1234567887654321L;\n    LongProperty longProperty = LongProperty.create(longValue);\n    assertEquals(singlePropertyHash(longValue), longProperty.hashCode());\n  }\n\n  @AutoValue\n  abstract static class IntProperty {\n    public abstract int intProperty();\n\n    public static IntProperty create(int intProperty) {\n      return new AutoValue_AutoValueTest_IntProperty(intProperty);\n    }\n  }\n\n  @Test\n  public void testIntHashCode() {\n    int intValue = 0x12345678;\n    IntProperty intProperty = IntProperty.create(intValue);\n    assertEquals(singlePropertyHash(intValue), intProperty.hashCode());\n  }\n\n  @AutoValue\n  abstract static class ShortProperty {\n    public abstract short shortProperty();\n\n    public static ShortProperty create(short shortProperty) {\n      return new AutoValue_AutoValueTest_ShortProperty(shortProperty);\n    }\n  }\n\n  @Test\n  public void testShortHashCode() {\n    short shortValue = 0x1234;\n    ShortProperty shortProperty = ShortProperty.create(shortValue);\n    assertEquals(singlePropertyHash(shortValue), shortProperty.hashCode());\n  }\n\n  @AutoValue\n  abstract static class ByteProperty {\n    public abstract byte byteProperty();\n\n    public static ByteProperty create(byte byteProperty) {\n      return new AutoValue_AutoValueTest_ByteProperty(byteProperty);\n    }\n  }\n\n  @Test\n  public void testByteHashCode() {\n    byte byteValue = 123;\n    ByteProperty byteProperty = ByteProperty.create(byteValue);\n    assertEquals(singlePropertyHash(byteValue), byteProperty.hashCode());\n  }\n\n  @AutoValue\n  abstract static class CharProperty {\n    public abstract char charProperty();\n\n    public static CharProperty create(char charProperty) {\n      return new AutoValue_AutoValueTest_CharProperty(charProperty);\n    }\n  }\n\n  @Test\n  public void testCharHashCode() {\n    char charValue = 123;\n    CharProperty charProperty = CharProperty.create(charValue);\n    assertEquals(singlePropertyHash(charValue), charProperty.hashCode());\n  }\n\n  @AutoValue\n  abstract static class BooleanProperty {\n    public abstract boolean booleanProperty();\n\n    public static BooleanProperty create(boolean booleanProperty) {\n      return new AutoValue_AutoValueTest_BooleanProperty(booleanProperty);\n    }\n  }\n\n  @Test\n  public void testBooleanHashCode() {\n    for (boolean booleanValue : new boolean[] {false, true}) {\n      BooleanProperty booleanProperty = BooleanProperty.create(booleanValue);\n      assertEquals(singlePropertyHash(booleanValue), booleanProperty.hashCode());\n    }\n  }\n\n  @AutoValue\n  abstract static class FloatProperty {\n    public abstract float floatProperty();\n\n    public static FloatProperty create(float floatProperty) {\n      return new AutoValue_AutoValueTest_FloatProperty(floatProperty);\n    }\n  }\n\n  @Test\n  public void testFloatHashCode() {\n    float floatValue = 123456f;\n    FloatProperty floatProperty = FloatProperty.create(floatValue);\n    assertEquals(singlePropertyHash(floatValue), floatProperty.hashCode());\n  }\n\n  @AutoValue\n  abstract static class DoubleProperty {\n    public abstract double doubleProperty();\n\n    public static DoubleProperty create(double doubleProperty) {\n      return new AutoValue_AutoValueTest_DoubleProperty(doubleProperty);\n    }\n  }\n\n  @Test\n  public void testDoubleHashCode() {\n    double doubleValue = 1234567890123456d;\n    DoubleProperty doubleProperty = DoubleProperty.create(doubleValue);\n    assertEquals(singlePropertyHash(doubleValue), doubleProperty.hashCode());\n  }\n\n  @Test\n  public void testFloatingEquality() {\n    FloatProperty floatZero = FloatProperty.create(0.0f);\n    FloatProperty floatMinusZero = FloatProperty.create(-0.0f);\n    FloatProperty floatNaN = FloatProperty.create(Float.NaN);\n    DoubleProperty doubleZero = DoubleProperty.create(0.0);\n    DoubleProperty doubleMinusZero = DoubleProperty.create(-0.0);\n    DoubleProperty doubleNaN = DoubleProperty.create(Double.NaN);\n    new EqualsTester()\n        .addEqualityGroup(floatZero)\n        .addEqualityGroup(floatMinusZero)\n        .addEqualityGroup(floatNaN)\n        .addEqualityGroup(doubleZero)\n        .addEqualityGroup(doubleMinusZero)\n        .addEqualityGroup(doubleNaN)\n        .testEquals();\n  }\n\n  private static int singlePropertyHash(Object property) {\n    return 1000003 ^ property.hashCode();\n  }\n\n  abstract static class Super {\n    public abstract Object superObject();\n\n    public abstract boolean superBoolean();\n    // The above two are out of alphabetical order to test EclipseHack.\n  }\n\n  @AutoValue\n  public abstract static class Sub extends Super {\n    public abstract int subInt();\n\n    public static Sub create(Object superObject, boolean superBoolean, int subInt) {\n      return new AutoValue_AutoValueTest_Sub(superObject, superBoolean, subInt);\n    }\n  }\n\n  // The @AutoValue class can inherit abstract methods from its superclass.\n  @Test\n  public void testSuperclass() throws Exception {\n    Sub instance = Sub.create(\"blim\", true, 1729);\n    assertEquals(\"blim\", instance.superObject());\n    assertTrue(instance.superBoolean());\n    assertEquals(1729, instance.subInt());\n    assertEquals(instance, instance);\n    assertEqualsNullIsFalse(instance);\n  }\n\n  abstract static class NonPublicSuper {\n    abstract Object superObject();\n  }\n\n  // The properties in this subclass are not in alphabetical order, which enables us to test that\n  // everything works correctly when Eclipse sorts them into the order\n  // [superObject, subInt, subString], since it sorts per class.\n  @AutoValue\n  abstract static class NonPublicSub extends NonPublicSuper {\n    abstract String subString();\n\n    abstract int subInt();\n\n    static NonPublicSub create(Object superObject, String subString, int subInt) {\n      return new AutoValue_AutoValueTest_NonPublicSub(superObject, subString, subInt);\n    }\n  }\n\n  @Test\n  public void testNonPublicInheritedGetters() throws Exception {\n    NonPublicSub instance = NonPublicSub.create(\"blim\", \"blam\", 1729);\n    assertEquals(\"blim\", instance.superObject());\n    assertEquals(\"blam\", instance.subString());\n    assertEquals(1729, instance.subInt());\n    assertEquals(instance, instance);\n    assertEqualsNullIsFalse(instance);\n  }\n\n  @SuppressWarnings(\"ObjectEqualsNull\")\n  private void assertEqualsNullIsFalse(Object instance) {\n    assertFalse(instance.equals(null));\n  }\n\n  @AutoValue\n  abstract static class NullableProperties {\n    @Nullable\n    abstract String nullableString();\n\n    abstract int randomInt();\n\n    static NullableProperties create(@Nullable String nullableString, int randomInt) {\n      return new AutoValue_AutoValueTest_NullableProperties(nullableString, randomInt);\n    }\n  }\n\n  @Test\n  public void testNullablePropertiesCanBeNull() {\n    NullableProperties instance = NullableProperties.create(null, 23);\n    assertNull(instance.nullableString());\n    assertThat(instance.randomInt()).isEqualTo(23);\n    String expectedString =\n        omitIdentifiers ? \"{null, 23}\" : \"NullableProperties{nullableString=null, randomInt=23}\";\n    assertThat(instance.toString()).isEqualTo(expectedString);\n  }\n\n  @AutoAnnotation\n  static Nullable nullable() {\n    return new AutoAnnotation_AutoValueTest_nullable();\n  }\n\n  @Test\n  public void testNullablePropertyConstructorParameterIsNullable() throws NoSuchMethodException {\n    Constructor<?> constructor =\n        AutoValue_AutoValueTest_NullableProperties.class.getDeclaredConstructor(\n            String.class, int.class);\n    assertThat(constructor.getParameterAnnotations()[0]).asList().contains(nullable());\n  }\n\n  @AutoValue\n  abstract static class AlternativeNullableProperties {\n    @interface Nullable {}\n\n    @AlternativeNullableProperties.Nullable\n    abstract String nullableString();\n\n    abstract int randomInt();\n\n    static AlternativeNullableProperties create(@Nullable String nullableString, int randomInt) {\n      return new AutoValue_AutoValueTest_AlternativeNullableProperties(nullableString, randomInt);\n    }\n  }\n\n  @Test\n  public void testNullableCanBeFromElsewhere() throws Exception {\n    AlternativeNullableProperties instance = AlternativeNullableProperties.create(null, 23);\n    assertNull(instance.nullableString());\n    assertThat(instance.randomInt()).isEqualTo(23);\n    String expectedString =\n        omitIdentifiers\n            ? \"{null, 23}\"\n            : \"AlternativeNullableProperties{nullableString=null, randomInt=23}\";\n    assertThat(instance.toString()).isEqualTo(expectedString);\n  }\n\n  @AutoValue\n  abstract static class NonNullableProperties {\n    abstract String nonNullableString();\n\n    abstract int randomInt();\n\n    static NonNullableProperties create(String nonNullableString, int randomInt) {\n      return new AutoValue_AutoValueTest_NonNullableProperties(nonNullableString, randomInt);\n    }\n  }\n\n  @Test\n  public void testNonNullablePropertiesCannotBeNull() throws Exception {\n    try {\n      NonNullableProperties.create(null, 23);\n      fail(\"Object creation succeeded but should not have\");\n    } catch (NullPointerException expected) {\n    }\n    NonNullableProperties instance = NonNullableProperties.create(\"nonnull\", 23);\n    assertEquals(\"nonnull\", instance.nonNullableString());\n    assertEquals(23, instance.randomInt());\n  }\n\n  @AutoValue\n  abstract static class NullableListProperties {\n    @Nullable\n    abstract ImmutableList<String> nullableStringList();\n\n    static NullableListProperties create(@Nullable ImmutableList<String> nullableStringList) {\n      return new AutoValue_AutoValueTest_NullableListProperties(nullableStringList);\n    }\n  }\n\n  @Test\n  public void testNullableListPropertiesCanBeNonNull() {\n    NullableListProperties instance = NullableListProperties.create(ImmutableList.of(\"foo\", \"bar\"));\n    assertEquals(ImmutableList.of(\"foo\", \"bar\"), instance.nullableStringList());\n  }\n\n  @Test\n  public void testNullableListPropertiesCanBeNull() {\n    NullableListProperties instance = NullableListProperties.create(null);\n    assertNull(instance.nullableStringList());\n  }\n\n  @AutoValue\n  abstract static class NullableListPropertiesWithBuilder {\n    @Nullable\n    abstract ImmutableList<String> nullableStringList();\n\n    static Builder builder() {\n      return new AutoValue_AutoValueTest_NullableListPropertiesWithBuilder.Builder();\n    }\n\n    @AutoValue.Builder\n    interface Builder {\n      Builder nullableStringList(List<String> nullableStringList);\n\n      NullableListPropertiesWithBuilder build();\n    }\n  }\n\n  @Test\n  public void testNullableListPropertiesWithBuilderCanBeNonNull() {\n    NullableListPropertiesWithBuilder instance =\n        NullableListPropertiesWithBuilder.builder()\n            .nullableStringList(ImmutableList.of(\"foo\", \"bar\"))\n            .build();\n    assertEquals(ImmutableList.of(\"foo\", \"bar\"), instance.nullableStringList());\n  }\n\n  @Test\n  public void testNullableListPropertiesWithBuilderCanBeUnset() {\n    NullableListPropertiesWithBuilder instance =\n        NullableListPropertiesWithBuilder.builder().build();\n    assertNull(instance.nullableStringList());\n  }\n\n  @Test\n  public void testNullableListPropertiesWithBuilderCanBeNull() {\n    NullableListPropertiesWithBuilder instance =\n        NullableListPropertiesWithBuilder.builder().nullableStringList(null).build();\n    assertNull(instance.nullableStringList());\n  }\n\n  static class Nested {\n    @AutoValue\n    abstract static class Doubly {\n      @Nullable\n      abstract String nullableString();\n\n      abstract int randomInt();\n\n      static Doubly create(String nullableString, int randomInt) {\n        return new AutoValue_AutoValueTest_Nested_Doubly(nullableString, randomInt);\n      }\n    }\n  }\n\n  @Test\n  public void testDoublyNestedClass() throws Exception {\n    Nested.Doubly instance = Nested.Doubly.create(null, 23);\n    assertNull(instance.nullableString());\n    assertThat(instance.randomInt()).isEqualTo(23);\n    String expectedString =\n        omitIdentifiers ? \"{null, 23}\" : \"Doubly{nullableString=null, randomInt=23}\";\n    assertThat(instance.toString()).isEqualTo(expectedString);\n  }\n\n  static interface NestedInInterface {\n    @AutoValue\n    abstract class Doubly {\n      abstract String string();\n\n      abstract Map<String, Integer> map();\n\n      static Doubly create(String string, Map<String, Integer> map) {\n        return new AutoValue_AutoValueTest_NestedInInterface_Doubly(string, map);\n      }\n    }\n  }\n\n  @Test\n  public void testClassNestedInInterface() throws Exception {\n    Map<String, Integer> map = ImmutableMap.of(\"vingt-et-un\", 21);\n    NestedInInterface.Doubly instance = NestedInInterface.Doubly.create(\"foo\", map);\n    assertEquals(\"foo\", instance.string());\n    assertEquals(map, instance.map());\n  }\n\n  @AutoValue\n  abstract static class NullableNonNullable {\n    @Nullable\n    abstract String nullableString();\n\n    @Nullable\n    abstract String otherNullableString();\n\n    abstract String nonNullableString();\n\n    static NullableNonNullable create(\n        String nullableString, String otherNullableString, String nonNullableString) {\n      return new AutoValue_AutoValueTest_NullableNonNullable(\n          nullableString, otherNullableString, nonNullableString);\n    }\n  }\n\n  @Test\n  public void testEqualsWithNullable() throws Exception {\n    NullableNonNullable everythingNull =\n        NullableNonNullable.create(null, null, \"nonNullableString\");\n    NullableNonNullable somethingNull =\n        NullableNonNullable.create(null, \"otherNullableString\", \"nonNullableString\");\n    NullableNonNullable nothingNull =\n        NullableNonNullable.create(\"nullableString\", \"otherNullableString\", \"nonNullableString\");\n    NullableNonNullable nothingNullAgain =\n        NullableNonNullable.create(\"nullableString\", \"otherNullableString\", \"nonNullableString\");\n    new EqualsTester()\n        .addEqualityGroup(everythingNull)\n        .addEqualityGroup(somethingNull)\n        .addEqualityGroup(nothingNull, nothingNullAgain)\n        .testEquals();\n  }\n\n  @AutoValue\n  abstract static class GenericProperties {\n    abstract Map<String, Integer> simpleMap();\n\n    abstract Map<String, Map<String, Integer>> hairyMap();\n\n    static GenericProperties create(\n        Map<String, Integer> simpleMap, Map<String, Map<String, Integer>> hairyMap) {\n      return new AutoValue_AutoValueTest_GenericProperties(simpleMap, hairyMap);\n    }\n  }\n\n  @Test\n  public void testGenericProperties() throws Exception {\n    GenericProperties instance1 =\n        GenericProperties.create(\n            ImmutableMap.of(\"twenty-three\", 23),\n            ImmutableMap.of(\"very\", (Map<String, Integer>) ImmutableMap.of(\"hairy\", 17)));\n    GenericProperties instance2 =\n        GenericProperties.create(\n            ImmutableMap.of(\"seventeen\", 17),\n            ImmutableMap.of(\"very\", (Map<String, Integer>) ImmutableMap.of(\"hairy\", 23)));\n    new EqualsTester().addEqualityGroup(instance1).addEqualityGroup(instance2).testEquals();\n    assertEquals(\n        ImmutableMap.of(\"very\", (Map<String, Integer>) ImmutableMap.of(\"hairy\", 23)),\n        instance2.hairyMap());\n  }\n\n  @AutoValue\n  abstract static class GenericClass<K, V> {\n    abstract K key();\n\n    abstract Map<K, V> map();\n\n    static <K, V> GenericClass<K, V> create(K key, Map<K, V> map) {\n      return new AutoValue_AutoValueTest_GenericClass<K, V>(key, map);\n    }\n  }\n\n  @Test\n  public void testGenericClass() throws Exception {\n    GenericClass<String, Boolean> instance =\n        GenericClass.create(\"whatever\", ImmutableMap.of(\"no\", false));\n    assertEquals(instance, instance);\n    assertEquals(\"whatever\", instance.key());\n    assertEquals(ImmutableMap.of(\"no\", false), instance.map());\n  }\n\n  @AutoValue\n  abstract static class GenericClassSimpleBounds<K extends Number, V extends K> {\n    abstract K key();\n\n    abstract Map<K, V> map();\n\n    static <K extends Number, V extends K> GenericClassSimpleBounds<K, V> create(\n        K key, Map<K, V> map) {\n      return new AutoValue_AutoValueTest_GenericClassSimpleBounds<K, V>(key, map);\n    }\n  }\n\n  @Test\n  public void testGenericClassWithSimpleBounds() throws Exception {\n    GenericClassSimpleBounds<Integer, Integer> instance =\n        GenericClassSimpleBounds.create(23, ImmutableMap.of(17, 23));\n    assertEquals(instance, instance);\n    assertEquals(23, (int) instance.key());\n    assertEquals(ImmutableMap.of(17, 23), instance.map());\n  }\n\n  @AutoValue\n  abstract static class GenericClassHairyBounds<K extends List<V> & Comparable<K>, V> {\n    abstract K key();\n\n    abstract Map<K, V> map();\n\n    static <K extends List<V> & Comparable<K>, V> GenericClassHairyBounds<K, V> create(\n        K key, Map<K, V> map) {\n      return new AutoValue_AutoValueTest_GenericClassHairyBounds<K, V>(key, map);\n    }\n  }\n\n  @Test\n  public void testGenericClassWithHairyBounds() throws Exception {\n    class ComparableList<E> extends ArrayList<E> implements Comparable<ComparableList<E>> {\n      private static final long serialVersionUID = 1L;\n\n      @Override\n      public int compareTo(ComparableList<E> list) {\n        throw new UnsupportedOperationException();\n      }\n    }\n    ComparableList<String> emptyList = new ComparableList<String>();\n    GenericClassHairyBounds<ComparableList<String>, String> instance =\n        GenericClassHairyBounds.create(emptyList, ImmutableMap.of(emptyList, \"23\"));\n    assertEquals(instance, instance);\n    assertEquals(emptyList, instance.key());\n    assertEquals(ImmutableMap.of(emptyList, \"23\"), instance.map());\n  }\n\n  interface Mergeable<M extends Mergeable<M>> {\n    M merge(M other);\n  }\n\n  @AutoValue\n  abstract static class Delta<M extends Mergeable<M>> {\n    abstract M meta();\n\n    static <M extends Mergeable<M>> Delta<M> create(M meta) {\n      return new AutoValue_AutoValueTest_Delta<M>(meta);\n    }\n  }\n\n  @Test\n  public void testRecursiveGeneric() {\n    class MergeableImpl implements Mergeable<MergeableImpl> {\n      @Override\n      public MergeableImpl merge(MergeableImpl other) {\n        return this;\n      }\n    }\n    MergeableImpl mergeable = new MergeableImpl();\n    Delta<MergeableImpl> instance = Delta.create(mergeable);\n    assertSame(mergeable, instance.meta());\n  }\n\n  static class NodeType<O> {}\n\n  abstract static class NodeExpressionClass<O> {\n    abstract NodeType<O> getType();\n  }\n\n  @AutoValue\n  abstract static class NotNodeExpression extends NodeExpressionClass<Boolean> {\n    static NotNodeExpression create() {\n      return new AutoValue_AutoValueTest_NotNodeExpression(new NodeType<Boolean>());\n    }\n  }\n\n  interface NodeExpressionInterface<O> {\n    NodeType<O> getType();\n  }\n\n  @AutoValue\n  abstract static class NotNodeExpression2 implements NodeExpressionInterface<Boolean> {\n    static NotNodeExpression2 create() {\n      return new AutoValue_AutoValueTest_NotNodeExpression2(new NodeType<Boolean>());\n    }\n  }\n\n  @Test\n  public void testConcreteWithGenericParent() {\n    NotNodeExpression instance = NotNodeExpression.create();\n    assertThat(instance.getType()).isInstanceOf(NodeType.class);\n    NotNodeExpression2 instance2 = NotNodeExpression2.create();\n    assertThat(instance2.getType()).isInstanceOf(NodeType.class);\n  }\n\n  @AutoValue\n  abstract static class ExplicitToString {\n    abstract String string();\n\n    static ExplicitToString create(String string) {\n      return new AutoValue_AutoValueTest_ExplicitToString(string);\n    }\n\n    @Override\n    public String toString() {\n      return \"Bazinga{\" + string() + \"}\";\n    }\n  }\n\n  // We should not generate a toString() method if there already is a non-default one.\n  @Test\n  public void testExplicitToString() throws Exception {\n    ExplicitToString instance = ExplicitToString.create(\"foo\");\n    assertEquals(\"Bazinga{foo}\", instance.toString());\n  }\n\n  abstract static class NonAutoExplicitToString {\n    abstract String string();\n\n    @Override\n    public String toString() {\n      return \"Bazinga{\" + string() + \"}\";\n    }\n  }\n\n  @AutoValue\n  abstract static class InheritedExplicitToString extends NonAutoExplicitToString {\n    static InheritedExplicitToString create(String string) {\n      return new AutoValue_AutoValueTest_InheritedExplicitToString(string);\n    }\n  }\n\n  // We should not generate a toString() method if we already inherit a non-default one.\n  @Test\n  public void testInheritedExplicitToString() throws Exception {\n    InheritedExplicitToString instance = InheritedExplicitToString.create(\"foo\");\n    assertEquals(\"Bazinga{foo}\", instance.toString());\n  }\n\n  @AutoValue\n  abstract static class AbstractToString {\n    abstract String string();\n\n    static AbstractToString create(String string) {\n      return new AutoValue_AutoValueTest_AbstractToString(string);\n    }\n\n    @Override\n    public abstract String toString();\n  }\n\n  // We should generate a toString() method if the parent class has an abstract one.\n  // That allows users to cancel a toString() from a parent class if they want.\n  @Test\n  public void testAbstractToString() throws Exception {\n    AbstractToString instance = AbstractToString.create(\"foo\");\n    String expectedString = omitIdentifiers ? \"{foo}\" : \"AbstractToString{string=foo}\";\n    assertThat(instance.toString()).isEqualTo(expectedString);\n  }\n\n  abstract static class NonAutoAbstractToString {\n    abstract String string();\n\n    @Override\n    public abstract String toString();\n  }\n\n  @AutoValue\n  abstract static class SubAbstractToString extends NonAutoAbstractToString {\n    static SubAbstractToString create(String string) {\n      return new AutoValue_AutoValueTest_SubAbstractToString(string);\n    }\n  }\n\n  // We should generate a toString() method if the parent class inherits an abstract one.\n  @Test\n  public void testInheritedAbstractToString() throws Exception {\n    SubAbstractToString instance = SubAbstractToString.create(\"foo\");\n    String expectedString = omitIdentifiers ? \"{foo}\" : \"SubAbstractToString{string=foo}\";\n    assertThat(instance.toString()).isEqualTo(expectedString);\n  }\n\n  @AutoValue\n  abstract static class ExplicitHashCode {\n    abstract String string();\n\n    static ExplicitHashCode create(String string) {\n      return new AutoValue_AutoValueTest_ExplicitHashCode(string);\n    }\n\n    @Override\n    public int hashCode() {\n      return 1234;\n    }\n  }\n\n  @Test\n  public void testExplicitHashCode() throws Exception {\n    ExplicitHashCode instance = ExplicitHashCode.create(\"foo\");\n    assertEquals(1234, instance.hashCode());\n  }\n\n  @AutoValue\n  @SuppressWarnings(\"EqualsHashCode\")\n  abstract static class ExplicitEquals {\n    int equalsCount;\n\n    static ExplicitEquals create() {\n      return new AutoValue_AutoValueTest_ExplicitEquals();\n    }\n\n    @Override\n    public boolean equals(Object o) {\n      equalsCount++;\n      return super.equals(o);\n    }\n  }\n\n  @SuppressWarnings(\"SelfEquals\")\n  @Test\n  public void testExplicitEquals() throws Exception {\n    ExplicitEquals instance = ExplicitEquals.create();\n    assertEquals(0, instance.equalsCount);\n    assertTrue(instance.equals(instance));\n    assertEquals(1, instance.equalsCount);\n    Method equals = instance.getClass().getMethod(\"equals\", Object.class);\n    assertNotSame(ExplicitEquals.class, instance.getClass());\n    assertSame(ExplicitEquals.class, equals.getDeclaringClass());\n  }\n\n  @Retention(RetentionPolicy.RUNTIME)\n  @interface MyAnnotation {\n    String value();\n  }\n\n  @AutoAnnotation\n  private static MyAnnotation myAnnotation(String value) {\n    return new AutoAnnotation_AutoValueTest_myAnnotation(value);\n  }\n\n  @AutoValue\n  abstract static class PrimitiveArrays {\n    @SuppressWarnings(\"mutable\")\n    abstract boolean[] booleans();\n\n    @SuppressWarnings(\"mutable\")\n    @Nullable\n    abstract int[] ints();\n\n    static PrimitiveArrays create(boolean[] booleans, int[] ints) {\n      // Real code would likely clone these parameters, but here we want to check that the\n      // generated constructor rejects a null value for booleans.\n      return new AutoValue_AutoValueTest_PrimitiveArrays(booleans, ints);\n    }\n  }\n\n  @Test\n  public void testPrimitiveArrays() {\n    PrimitiveArrays object0 = PrimitiveArrays.create(new boolean[0], new int[0]);\n    boolean[] booleans = {false, true, true, false};\n    int[] ints = {6, 28, 496, 8128, 33550336};\n    PrimitiveArrays object1 = PrimitiveArrays.create(booleans.clone(), ints.clone());\n    PrimitiveArrays object2 = PrimitiveArrays.create(booleans.clone(), ints.clone());\n    new EqualsTester().addEqualityGroup(object1, object2).addEqualityGroup(object0).testEquals();\n    // EqualsTester also exercises hashCode(). We clone the arrays above to ensure that using the\n    // default Object.hashCode() will fail.\n\n    String expectedString =\n        omitIdentifiers\n            ? (\"{\" + Arrays.toString(booleans) + \", \" + Arrays.toString(ints) + \"}\")\n            : (\"PrimitiveArrays{booleans=\"\n                + Arrays.toString(booleans)\n                + \", \"\n                + \"ints=\"\n                + Arrays.toString(ints)\n                + \"}\");\n    assertThat(object1.toString()).isEqualTo(expectedString);\n    assertThat(object1.ints()).isSameInstanceAs(object1.ints());\n  }\n\n  @Test\n  public void testNullablePrimitiveArrays() {\n    PrimitiveArrays object0 = PrimitiveArrays.create(new boolean[0], null);\n    boolean[] booleans = {false, true, true, false};\n    PrimitiveArrays object1 = PrimitiveArrays.create(booleans.clone(), null);\n    PrimitiveArrays object2 = PrimitiveArrays.create(booleans.clone(), null);\n    new EqualsTester().addEqualityGroup(object1, object2).addEqualityGroup(object0).testEquals();\n\n    String expectedString =\n        omitIdentifiers\n            ? (\"{\" + Arrays.toString(booleans) + \", null}\")\n            : (\"PrimitiveArrays{booleans=\" + Arrays.toString(booleans) + \", \" + \"ints=null}\");\n    assertThat(object1.toString()).isEqualTo(expectedString);\n\n    assertThat(object1.booleans()).isSameInstanceAs(object1.booleans());\n    assertThat(object1.booleans()).isEqualTo(booleans);\n    object1.booleans()[0] ^= true;\n    assertThat(object1.booleans()).isNotEqualTo(booleans);\n  }\n\n  @Test\n  public void testNotNullablePrimitiveArrays() {\n    try {\n      PrimitiveArrays.create(null, new int[0]);\n      fail(\"Construction with null value for non-@Nullable array should have failed\");\n    } catch (NullPointerException e) {\n      if (omitIdentifiers) {\n        assertThat(e).hasMessageThat().isNull();\n      } else {\n        assertThat(e).hasMessageThat().contains(\"booleans\");\n      }\n    }\n  }\n\n  // If users are mad enough to define their own Arrays class and have some properties of that\n  // class and others of primitive array type, then we can't import java.util.Arrays.\n  // This is unlikely.\n  @AutoValue\n  abstract static class AmbiguousArrays {\n    static class Arrays {}\n\n    abstract Arrays arrays();\n\n    @SuppressWarnings(\"mutable\")\n    abstract int[] ints();\n\n    static AmbiguousArrays create(Arrays arrays, int[] ints) {\n      return new AutoValue_AutoValueTest_AmbiguousArrays(arrays, ints);\n    }\n  }\n\n  @Test\n  public void testAmbiguousArrays() {\n    // If this test compiles at all then we presumably don't have the import problem above.\n    AmbiguousArrays object1 = AmbiguousArrays.create(new AmbiguousArrays.Arrays(), new int[0]);\n    assertNotNull(object1.arrays());\n    assertEquals(0, object1.ints().length);\n  }\n\n  static final class HashCodeObserver {\n    int hashCodeCount;\n\n    @Override\n    public boolean equals(Object obj) {\n      return obj instanceof HashCodeObserver;\n    }\n\n    @Override\n    public int hashCode() {\n      hashCodeCount++;\n      return 23;\n    }\n  }\n\n  @AutoValue\n  abstract static class MaybeCachedHashCode {\n    abstract HashCodeObserver hashCodeObserver();\n\n    abstract int randomInt();\n\n    static MaybeCachedHashCode create(HashCodeObserver hashCodeObserver, int randomInt) {\n      return new AutoValue_AutoValueTest_MaybeCachedHashCode(hashCodeObserver, randomInt);\n    }\n  }\n\n  @Test\n  public void testHashCodeNotCached() {\n    HashCodeObserver observer = new HashCodeObserver();\n    MaybeCachedHashCode maybeCached = MaybeCachedHashCode.create(observer, 17);\n    int hash1 = maybeCached.hashCode();\n    int hash2 = maybeCached.hashCode();\n    assertEquals(hash1, hash2);\n    assertEquals(2, observer.hashCodeCount);\n  }\n\n  @AutoValue\n  abstract static class Version implements Comparable<Version> {\n    abstract int major();\n\n    abstract int minor();\n\n    static Version create(int major, int minor) {\n      return new AutoValue_AutoValueTest_Version(major, minor);\n    }\n\n    @Override\n    public int compareTo(Version that) {\n      return ComparisonChain.start()\n          .compare(this.major(), that.major())\n          .compare(this.minor(), that.minor())\n          .result();\n    }\n  }\n\n  @Test\n  public void testComparisonChain() {\n    assertEquals(Version.create(1, 2), Version.create(1, 2));\n    Version[] versions = {Version.create(1, 2), Version.create(1, 3), Version.create(2, 1)};\n    for (int i = 0; i < versions.length; i++) {\n      for (int j = 0; j < versions.length; j++) {\n        int actual = Integer.signum(versions[i].compareTo(versions[j]));\n        int expected = Integer.signum(i - j);\n        assertEquals(expected, actual);\n      }\n    }\n  }\n\n  abstract static class LukesBase {\n    interface LukesVisitor<T> {\n      T visit(LukesSub s);\n    }\n\n    abstract <T> T accept(LukesVisitor<T> visitor);\n\n    @AutoValue\n    abstract static class LukesSub extends LukesBase {\n      static LukesSub create() {\n        return new AutoValue_AutoValueTest_LukesBase_LukesSub();\n      }\n\n      @Override\n      <T> T accept(LukesVisitor<T> visitor) {\n        return visitor.visit(this);\n      }\n    }\n  }\n\n  @Test\n  public void testVisitor() {\n    LukesBase.LukesVisitor<String> visitor =\n        new LukesBase.LukesVisitor<String>() {\n          @Override\n          public String visit(LukesBase.LukesSub s) {\n            return s.toString();\n          }\n        };\n    LukesBase.LukesSub sub = LukesBase.LukesSub.create();\n    assertEquals(sub.toString(), sub.accept(visitor));\n  }\n\n  @AutoValue\n  public abstract static class ComplexInheritance extends AbstractBase implements IntfA, IntfB {\n    public static ComplexInheritance create(String name) {\n      return new AutoValue_AutoValueTest_ComplexInheritance(name);\n    }\n\n    abstract String name();\n  }\n\n  static class AbstractBase implements Base {\n    @Override\n    public int answer() {\n      return 42;\n    }\n  }\n\n  interface IntfA extends Base {}\n\n  interface IntfB extends Base {}\n\n  interface Base {\n    int answer();\n  }\n\n  @Test\n  public void testComplexInheritance() {\n    ComplexInheritance complex = ComplexInheritance.create(\"fred\");\n    assertEquals(\"fred\", complex.name());\n    assertEquals(42, complex.answer());\n  }\n\n  // This tests the case where we inherit abstract methods on more than one path. AbstractList\n  // extends AbstractCollection, which implements Collection; and AbstractList also implements List,\n  // which extends Collection. So the class here inherits the methods of Collection on more than\n  // one path. In an earlier version of the logic for handling inheritance, this confused us into\n  // thinking that the methods from Collection were still abstract and therefore candidates for\n  // implementation, even though we inherit concrete implementations of them from AbstractList.\n  @AutoValue\n  public abstract static class MoreComplexInheritance extends AbstractList<String> {\n    @Override\n    public String get(int index) {\n      throw new NoSuchElementException(String.valueOf(index));\n    }\n\n    @Override\n    public int size() {\n      return 0;\n    }\n\n    public static MoreComplexInheritance create() {\n      return new AutoValue_AutoValueTest_MoreComplexInheritance();\n    }\n  }\n\n  @Test\n  public void testMoreComplexInheritance() {\n    MoreComplexInheritance instance1 = MoreComplexInheritance.create();\n    MoreComplexInheritance instance2 = MoreComplexInheritance.create();\n    assertThat(instance1).isEqualTo(instance2);\n    assertThat(instance1).isNotSameInstanceAs(instance2);\n  }\n\n  // Test that we are not misled by the privateness of an ancestor into thinking that its methods\n  // are invisible to descendants.\n  public abstract static class PublicGrandparent {\n    public abstract String foo();\n  }\n\n  private static class PrivateParent extends PublicGrandparent {\n    @Override\n    public String foo() {\n      return \"foo\";\n    }\n  }\n\n  @AutoValue\n  abstract static class EffectiveVisibility extends PrivateParent {\n    static EffectiveVisibility create() {\n      return new AutoValue_AutoValueTest_EffectiveVisibility();\n    }\n  }\n\n  @Test\n  public void testEffectiveVisibility() {\n    EffectiveVisibility instance1 = EffectiveVisibility.create();\n    EffectiveVisibility instance2 = EffectiveVisibility.create();\n    assertThat(instance1).isEqualTo(instance2);\n    assertThat(instance1).isNotSameInstanceAs(instance2);\n  }\n\n  @AutoValue\n  public abstract static class InheritTwice implements IntfA, IntfB {\n    public static InheritTwice create(int answer) {\n      return new AutoValue_AutoValueTest_InheritTwice(answer);\n    }\n  }\n\n  @Test\n  public void testInheritTwice() {\n    InheritTwice inheritTwice = InheritTwice.create(42);\n    assertEquals(42, inheritTwice.answer());\n  }\n\n  @AutoValue\n  public abstract static class Optional {\n    public abstract com.google.common.base.Optional<Object> getOptional();\n\n    public static Optional create(com.google.common.base.Optional<Object> opt) {\n      return new AutoValue_AutoValueTest_Optional(opt);\n    }\n  }\n\n  @Test\n  public void testAmbiguityFromAutoValueType() {\n    Optional autoOptional = Optional.create(com.google.common.base.Optional.absent());\n    assertEquals(com.google.common.base.Optional.absent(), autoOptional.getOptional());\n  }\n\n  static class BaseWithNestedType {\n    static class Optional {}\n  }\n\n  @AutoValue\n  public abstract static class InheritsNestedType extends BaseWithNestedType {\n    public abstract com.google.common.base.Optional<Object> getOptional();\n\n    public static InheritsNestedType create(com.google.common.base.Optional<Object> opt) {\n      return new AutoValue_AutoValueTest_InheritsNestedType(opt);\n    }\n  }\n\n  @Test\n  public void testAmbiguityFromInheritedType() {\n    InheritsNestedType inheritsNestedType =\n        InheritsNestedType.create(com.google.common.base.Optional.absent());\n    assertEquals(com.google.common.base.Optional.absent(), inheritsNestedType.getOptional());\n  }\n\n  abstract static class AbstractParent {\n    abstract int foo();\n  }\n\n  // We use Double.doubleToLongBits in equals and hashCode, so that better be qualified correctly if\n  // someone has unwisely declared their own Float or Double class.\n  @SuppressWarnings(\"JavaLangClash\")\n  @AutoValue\n  public abstract static class RedeclareFloatAndDouble {\n    public abstract float aFloat();\n\n    public abstract double aDouble();\n\n    public static RedeclareFloatAndDouble of(float aFloat, double aDouble) {\n      return new AutoValue_AutoValueTest_RedeclareFloatAndDouble(aFloat, aDouble);\n    }\n\n    static class Float {}\n\n    static class Double {}\n  }\n\n  @SuppressWarnings(\"TruthSelfEquals\")\n  @Test\n  public void testRedeclareFloatAndDouble() {\n    RedeclareFloatAndDouble iEqualMyself = RedeclareFloatAndDouble.of(Float.NaN, Double.NaN);\n    assertThat(iEqualMyself).isEqualTo(iEqualMyself);\n  }\n\n  @AutoValue\n  abstract static class AbstractChild extends AbstractParent {\n    // The main point of this test is to ensure that we don't try to copy this @Override into the\n    // generated implementation alongside the @Override that we put on all implementation methods.\n    @Override\n    abstract int foo();\n\n    static AbstractChild create(int foo) {\n      return new AutoValue_AutoValueTest_AbstractChild(foo);\n    }\n  }\n\n  @Test\n  public void testOverrideNotDuplicated() {\n    AbstractChild instance = AbstractChild.create(23);\n    assertEquals(23, instance.foo());\n  }\n\n  @AutoValue\n  public abstract static class BasicWithBuilder {\n    public abstract int foo();\n\n    public static Builder builder() {\n      return new AutoValue_AutoValueTest_BasicWithBuilder.Builder();\n    }\n\n    @AutoValue.Builder\n    public interface Builder {\n      Builder foo(int foo);\n\n      BasicWithBuilder build();\n    }\n  }\n\n  @Test\n  public void testBasicWithBuilder() {\n    BasicWithBuilder x = BasicWithBuilder.builder().foo(23).build();\n    assertEquals(23, x.foo());\n    try {\n      BasicWithBuilder.builder().build();\n      fail(\"Expected exception for missing property\");\n    } catch (IllegalStateException e) {\n      if (omitIdentifiers) {\n        assertThat(e).hasMessageThat().isNull();\n      } else {\n        assertThat(e).hasMessageThat().contains(\"foo\");\n      }\n    }\n  }\n\n  @Test\n  public void testBasicWithBuilderHasOnlyOneConstructor() throws Exception {\n    Class<?> builderClass = AutoValue_AutoValueTest_BasicWithBuilder.Builder.class;\n    Constructor<?>[] constructors = builderClass.getDeclaredConstructors();\n    assertThat(constructors).hasLength(1);\n    Constructor<?> constructor = constructors[0];\n    assertThat(constructor.getParameterTypes()).isEmpty();\n  }\n\n  @AutoValue\n  public abstract static class EmptyWithBuilder {\n    public static Builder builder() {\n      return new AutoValue_AutoValueTest_EmptyWithBuilder.Builder();\n    }\n\n    @AutoValue.Builder\n    public interface Builder {\n      EmptyWithBuilder build();\n    }\n  }\n\n  @Test\n  public void testEmptyWithBuilder() {\n    EmptyWithBuilder x = EmptyWithBuilder.builder().build();\n    EmptyWithBuilder y = EmptyWithBuilder.builder().build();\n    assertEquals(x, y);\n  }\n\n  @AutoValue\n  public abstract static class TwoPropertiesWithBuilderClass {\n    public abstract String string();\n\n    public abstract int integer();\n\n    public static Builder builder() {\n      return new AutoValue_AutoValueTest_TwoPropertiesWithBuilderClass.Builder();\n    }\n\n    public static Builder builder(String string) {\n      return new AutoValue_AutoValueTest_TwoPropertiesWithBuilderClass.Builder().string(string);\n    }\n\n    @AutoValue.Builder\n    public abstract static class Builder {\n      public abstract Builder string(String x);\n\n      public abstract Builder integer(int x);\n\n      public abstract TwoPropertiesWithBuilderClass build();\n    }\n  }\n\n  @Test\n  public void testTwoPropertiesWithBuilderClass() {\n    TwoPropertiesWithBuilderClass a1 =\n        TwoPropertiesWithBuilderClass.builder().string(\"23\").integer(17).build();\n    TwoPropertiesWithBuilderClass a2 =\n        TwoPropertiesWithBuilderClass.builder(\"23\").integer(17).build();\n    TwoPropertiesWithBuilderClass a3 =\n        TwoPropertiesWithBuilderClass.builder().integer(17).string(\"23\").build();\n    TwoPropertiesWithBuilderClass b =\n        TwoPropertiesWithBuilderClass.builder().string(\"17\").integer(17).build();\n    new EqualsTester().addEqualityGroup(a1, a2, a3).addEqualityGroup(b).testEquals();\n\n    try {\n      TwoPropertiesWithBuilderClass.builder().string(null);\n      fail(\"Did not get expected exception\");\n    } catch (NullPointerException expected) {\n    }\n  }\n\n  @AutoValue\n  public abstract static class NullablePropertyWithBuilder {\n    public abstract String notNullable();\n\n    @Nullable\n    public abstract String nullable();\n\n    public static Builder builder() {\n      return new AutoValue_AutoValueTest_NullablePropertyWithBuilder.Builder();\n    }\n\n    @AutoValue.Builder\n    public interface Builder {\n      Builder notNullable(String s);\n\n      Builder nullable(@Nullable String s);\n\n      NullablePropertyWithBuilder build();\n    }\n  }\n\n  @Test\n  public void testOmitNullableWithBuilder() {\n    NullablePropertyWithBuilder instance1 =\n        NullablePropertyWithBuilder.builder().notNullable(\"hello\").build();\n    assertThat(instance1.notNullable()).isEqualTo(\"hello\");\n    assertThat(instance1.nullable()).isNull();\n\n    NullablePropertyWithBuilder instance2 =\n        NullablePropertyWithBuilder.builder().notNullable(\"hello\").nullable(null).build();\n    assertThat(instance2.notNullable()).isEqualTo(\"hello\");\n    assertThat(instance2.nullable()).isNull();\n    assertThat(instance1).isEqualTo(instance2);\n\n    NullablePropertyWithBuilder instance3 =\n        NullablePropertyWithBuilder.builder().notNullable(\"hello\").nullable(\"world\").build();\n    assertThat(instance3.notNullable()).isEqualTo(\"hello\");\n    assertThat(instance3.nullable()).isEqualTo(\"world\");\n\n    try {\n      NullablePropertyWithBuilder.builder().build();\n      fail(\"Expected IllegalStateException for unset non-@Nullable property\");\n    } catch (IllegalStateException e) {\n      if (omitIdentifiers) {\n        assertThat(e).hasMessageThat().isNull();\n      } else {\n        assertThat(e).hasMessageThat().contains(\"notNullable\");\n      }\n    }\n  }\n\n  @AutoValue\n  public abstract static class PrimitiveAndBoxed {\n    public abstract int anInt();\n\n    @Nullable\n    public abstract Integer aNullableInteger();\n\n    @SuppressWarnings(\"AutoValueBoxedValues\")\n    public abstract Integer aNonNullableInteger();\n\n    public abstract Builder toBuilder();\n\n    public static Builder builder() {\n      return new AutoValue_AutoValueTest_PrimitiveAndBoxed.Builder();\n    }\n\n    @AutoValue.Builder\n    public interface Builder {\n      Builder setAnInt(int x);\n\n      Builder setANullableInteger(int x);\n\n      Builder setANonNullableInteger(int x);\n\n      PrimitiveAndBoxed build();\n    }\n  }\n\n  @Test\n  public void testPrimitiveAndBoxed() {\n    PrimitiveAndBoxed instance1 =\n        PrimitiveAndBoxed.builder().setAnInt(17).setANonNullableInteger(23).build();\n    assertThat(instance1.anInt()).isEqualTo(17);\n    assertThat(instance1.aNullableInteger()).isNull();\n    assertThat(instance1.aNonNullableInteger()).isEqualTo(23);\n\n    PrimitiveAndBoxed instance2 = instance1.toBuilder().setANullableInteger(5).build();\n    assertThat(instance2.aNullableInteger()).isEqualTo(5);\n  }\n\n  @AutoValue\n  public abstract static class OptionalPropertiesWithBuilder {\n    public abstract com.google.common.base.Optional<String> optionalString();\n\n    public abstract com.google.common.base.Optional<Integer> optionalInteger();\n\n    public static Builder builder() {\n      return new AutoValue_AutoValueTest_OptionalPropertiesWithBuilder.Builder();\n    }\n\n    @AutoValue.Builder\n    public interface Builder {\n      Builder setOptionalString(com.google.common.base.Optional<String> s);\n\n      Builder setOptionalString(String s);\n\n      Builder setOptionalInteger(com.google.common.base.Optional<Integer> i);\n\n      Builder setOptionalInteger(int i);\n\n      OptionalPropertiesWithBuilder build();\n    }\n  }\n\n  @Test\n  public void testOmitOptionalWithBuilder() {\n    OptionalPropertiesWithBuilder omitted = OptionalPropertiesWithBuilder.builder().build();\n    assertThat(omitted.optionalString()).isAbsent();\n    assertThat(omitted.optionalInteger()).isAbsent();\n\n    OptionalPropertiesWithBuilder supplied =\n        OptionalPropertiesWithBuilder.builder()\n            .setOptionalString(com.google.common.base.Optional.of(\"foo\"))\n            .build();\n    assertThat(supplied.optionalString()).hasValue(\"foo\");\n    assertThat(omitted.optionalInteger()).isAbsent();\n\n    OptionalPropertiesWithBuilder suppliedDirectly =\n        OptionalPropertiesWithBuilder.builder()\n            .setOptionalString(\"foo\")\n            .setOptionalInteger(23)\n            .build();\n    assertThat(suppliedDirectly.optionalString()).hasValue(\"foo\");\n    assertThat(suppliedDirectly.optionalInteger()).hasValue(23);\n\n    try {\n      // The parameter is not marked @Nullable so this should fail.\n      OptionalPropertiesWithBuilder.builder().setOptionalString((String) null);\n      fail();\n    } catch (NullPointerException expected) {\n    }\n  }\n\n  @AutoValue\n  public abstract static class OptionalPropertyWithNullableBuilder {\n    public abstract String notOptional();\n\n    public abstract com.google.common.base.Optional<String> optional();\n\n    public static Builder builder() {\n      return new AutoValue_AutoValueTest_OptionalPropertyWithNullableBuilder.Builder();\n    }\n\n    @AutoValue.Builder\n    public interface Builder {\n      Builder notOptional(String s);\n\n      Builder optional(@Nullable String s);\n\n      OptionalPropertyWithNullableBuilder build();\n    }\n  }\n\n  @Test\n  public void testOmitOptionalWithNullableBuilder() {\n    OptionalPropertyWithNullableBuilder instance1 =\n        OptionalPropertyWithNullableBuilder.builder().notOptional(\"hello\").build();\n    assertThat(instance1.notOptional()).isEqualTo(\"hello\");\n    assertThat(instance1.optional()).isAbsent();\n\n    OptionalPropertyWithNullableBuilder instance2 =\n        OptionalPropertyWithNullableBuilder.builder().notOptional(\"hello\").optional(null).build();\n    assertThat(instance2.notOptional()).isEqualTo(\"hello\");\n    assertThat(instance2.optional()).isAbsent();\n    assertThat(instance1).isEqualTo(instance2);\n\n    OptionalPropertyWithNullableBuilder instance3 =\n        OptionalPropertyWithNullableBuilder.builder()\n            .notOptional(\"hello\")\n            .optional(\"world\")\n            .build();\n    assertThat(instance3.notOptional()).isEqualTo(\"hello\");\n    assertThat(instance3.optional()).hasValue(\"world\");\n\n    try {\n      OptionalPropertyWithNullableBuilder.builder().build();\n      fail(\"Expected IllegalStateException for unset non-Optional property\");\n    } catch (IllegalStateException expected) {\n    }\n  }\n\n  @AutoValue\n  public abstract static class NullableOptionalPropertiesWithBuilder {\n    @Nullable\n    public abstract com.google.common.base.Optional<String> optionalString();\n\n    public static Builder builder() {\n      return new AutoValue_AutoValueTest_NullableOptionalPropertiesWithBuilder.Builder();\n    }\n\n    @AutoValue.Builder\n    public interface Builder {\n      Builder setOptionalString(com.google.common.base.Optional<String> s);\n\n      NullableOptionalPropertiesWithBuilder build();\n    }\n  }\n\n  @Test\n  public void testOmitNullableOptionalWithBuilder() {\n    NullableOptionalPropertiesWithBuilder omitted =\n        NullableOptionalPropertiesWithBuilder.builder().build();\n    assertThat(omitted.optionalString()).isNull();\n\n    NullableOptionalPropertiesWithBuilder supplied =\n        NullableOptionalPropertiesWithBuilder.builder()\n            .setOptionalString(com.google.common.base.Optional.of(\"foo\"))\n            .build();\n    assertThat(supplied.optionalString()).hasValue(\"foo\");\n  }\n\n  @AutoValue\n  public abstract static class OptionalPropertiesWithBuilderSimpleSetter {\n    public abstract com.google.common.base.Optional<String> optionalString();\n\n    public static Builder builder() {\n      return new AutoValue_AutoValueTest_OptionalPropertiesWithBuilderSimpleSetter.Builder();\n    }\n\n    @AutoValue.Builder\n    public interface Builder {\n      Builder setOptionalString(String s);\n\n      OptionalPropertiesWithBuilderSimpleSetter build();\n    }\n  }\n\n  @Test\n  public void testOptionalPropertySimpleSetter() {\n    OptionalPropertiesWithBuilderSimpleSetter omitted =\n        OptionalPropertiesWithBuilderSimpleSetter.builder().build();\n    assertThat(omitted.optionalString()).isAbsent();\n\n    OptionalPropertiesWithBuilderSimpleSetter supplied =\n        OptionalPropertiesWithBuilderSimpleSetter.builder().setOptionalString(\"foo\").build();\n    assertThat(supplied.optionalString()).hasValue(\"foo\");\n  }\n\n  @AutoValue\n  public abstract static class PropertyWithOptionalGetter {\n    public abstract String getString();\n\n    public abstract int getInt();\n\n    public static Builder builder() {\n      return new AutoValue_AutoValueTest_PropertyWithOptionalGetter.Builder();\n    }\n\n    @AutoValue.Builder\n    public interface Builder {\n      Builder setString(String s);\n\n      com.google.common.base.Optional<String> getString();\n\n      Builder setInt(int x);\n\n      com.google.common.base.Optional<Integer> getInt();\n\n      PropertyWithOptionalGetter build();\n    }\n  }\n\n  @Test\n  public void testOptionalGetter() {\n    PropertyWithOptionalGetter.Builder omitted = PropertyWithOptionalGetter.builder();\n    assertThat(omitted.getString()).isAbsent();\n    assertThat(omitted.getInt()).isAbsent();\n\n    PropertyWithOptionalGetter.Builder supplied =\n        PropertyWithOptionalGetter.builder().setString(\"foo\").setInt(23);\n    assertThat(supplied.getString()).hasValue(\"foo\");\n    assertThat(supplied.getInt()).hasValue(23);\n  }\n\n  @AutoValue\n  public abstract static class PropertyNamedMissing {\n    public abstract String missing();\n\n    public static Builder builder() {\n      return new AutoValue_AutoValueTest_PropertyNamedMissing.Builder();\n    }\n\n    @AutoValue.Builder\n    public abstract static class Builder {\n      public abstract Builder setMissing(String x);\n\n      public abstract PropertyNamedMissing build();\n    }\n  }\n\n  // https://github.com/google/auto/issues/412\n  @Test\n  public void testPropertyNamedMissing() {\n    try {\n      PropertyNamedMissing.builder().build();\n      fail();\n    } catch (IllegalStateException expected) {\n    }\n    PropertyNamedMissing x = PropertyNamedMissing.builder().setMissing(\"foo\").build();\n    assertThat(x.missing()).isEqualTo(\"foo\");\n  }\n\n  @AutoValue\n  public abstract static class GenericsWithBuilder<T extends Number & Comparable<T>, U extends T> {\n    public abstract List<T> list();\n\n    public abstract U u();\n\n    public static <T extends Number & Comparable<T>, U extends T> Builder<T, U> builder() {\n      return new AutoValue_AutoValueTest_GenericsWithBuilder.Builder<T, U>();\n    }\n\n    public abstract Builder<T, U> toBuilderGenerated();\n\n    @AutoValue.Builder\n    public interface Builder<T extends Number & Comparable<T>, U extends T> {\n      Builder<T, U> list(List<T> list);\n\n      Builder<T, U> u(U u);\n\n      GenericsWithBuilder<T, U> build();\n    }\n  }\n\n  @Test\n  public void testBuilderGenerics() {\n    List<Integer> integers = ImmutableList.of(1, 2, 3);\n    GenericsWithBuilder<Integer, Integer> instance =\n        GenericsWithBuilder.<Integer, Integer>builder().list(integers).u(23).build();\n    assertEquals(integers, instance.list());\n    assertEquals((Integer) 23, instance.u());\n\n    GenericsWithBuilder<Integer, Integer> instance2 = instance.toBuilderGenerated().build();\n    assertEquals(instance, instance2);\n    assertNotSame(instance, instance2);\n\n    GenericsWithBuilder<Integer, Integer> instance3 = instance.toBuilderGenerated().u(17).build();\n    assertEquals(integers, instance3.list());\n    assertEquals((Integer) 17, instance3.u());\n  }\n\n  public interface ToBuilder<BuilderT> {\n    BuilderT toBuilder();\n  }\n\n  @AutoValue\n  public abstract static class InheritedToBuilder<T, U>\n      implements ToBuilder<InheritedToBuilder.Builder<T, U>> {\n\n    public abstract T t();\n\n    public abstract U u();\n\n    public static <T, U> Builder<T, U> builder() {\n      return new AutoValue_AutoValueTest_InheritedToBuilder.Builder<T, U>();\n    }\n\n    @AutoValue.Builder\n    public abstract static class Builder<T, U> {\n      public abstract Builder<T, U> setT(T t);\n\n      public abstract Builder<T, U> setU(U u);\n\n      public abstract InheritedToBuilder<T, U> build();\n    }\n  }\n\n  @Test\n  public void testInheritedToBuilder() {\n    InheritedToBuilder<Integer, String> x =\n        InheritedToBuilder.<Integer, String>builder().setT(17).setU(\"wibble\").build();\n    InheritedToBuilder<Integer, String> y = x.toBuilder().setT(23).build();\n    assertThat(y.u()).isEqualTo(\"wibble\");\n  }\n\n  @AutoValue\n  public abstract static class BuilderWithSet<T extends Comparable<T>> {\n    public abstract List<T> list();\n\n    public abstract T t();\n\n    public static <T extends Comparable<T>> Builder<T> builder() {\n      return new AutoValue_AutoValueTest_BuilderWithSet.Builder<T>();\n    }\n\n    @AutoValue.Builder\n    public interface Builder<T extends Comparable<T>> {\n      Builder<T> setList(List<T> list);\n\n      Builder<T> setT(T t);\n\n      BuilderWithSet<T> build();\n    }\n  }\n\n  @Test\n  public void testBuilderWithSet() {\n    List<Integer> integers = ImmutableList.of(1, 2, 3);\n    BuilderWithSet<Integer> instance =\n        BuilderWithSet.<Integer>builder().setList(integers).setT(23).build();\n    assertEquals(integers, instance.list());\n    assertEquals((Integer) 23, instance.t());\n  }\n\n  @AutoValue\n  public abstract static class BuilderWithSetAndGet {\n    public abstract List<Integer> getAList();\n\n    public abstract int getAnInt();\n\n    public static Builder builder() {\n      return new AutoValue_AutoValueTest_BuilderWithSetAndGet.Builder();\n    }\n\n    public abstract Builder toBuilder();\n\n    @AutoValue.Builder\n    public interface Builder {\n      Builder setAList(List<Integer> list);\n\n      Builder setAnInt(int i);\n\n      BuilderWithSetAndGet build();\n    }\n  }\n\n  @Test\n  public void testBuilderWithSetAndGet() {\n    List<Integer> integers = ImmutableList.of(1, 2, 3);\n    BuilderWithSetAndGet instance =\n        BuilderWithSetAndGet.builder().setAList(integers).setAnInt(23).build();\n    assertEquals(integers, instance.getAList());\n    assertEquals(23, instance.getAnInt());\n\n    BuilderWithSetAndGet instance2 = instance.toBuilder().build();\n    assertEquals(instance, instance2);\n    assertNotSame(instance, instance2);\n\n    BuilderWithSetAndGet instance3 = instance.toBuilder().setAnInt(17).build();\n    assertEquals(integers, instance3.getAList());\n    assertEquals(17, instance3.getAnInt());\n  }\n\n  @AutoValue\n  public abstract static class BuilderWithUnprefixedGetters<T extends Comparable<T>> {\n    public abstract ImmutableList<T> list();\n\n    @Nullable\n    public abstract T t();\n\n    @SuppressWarnings(\"mutable\")\n    public abstract int[] ints();\n\n    public abstract int noGetter();\n\n    public abstract String oAuth();\n\n    public abstract String oBrien();\n\n    public static <T extends Comparable<T>> Builder<T> builder() {\n      return new AutoValue_AutoValueTest_BuilderWithUnprefixedGetters.Builder<T>();\n    }\n\n    @AutoValue.Builder\n    public interface Builder<T extends Comparable<T>> {\n      Builder<T> setList(ImmutableList<T> list);\n\n      Builder<T> setT(T t);\n\n      Builder<T> setInts(int[] ints);\n\n      Builder<T> setNoGetter(int x);\n\n      Builder<T> setoAuth(String x); // this ugly spelling is for compatibility\n\n      Builder<T> setOBrien(String x);\n\n      ImmutableList<T> list();\n\n      T t();\n\n      int[] ints();\n\n      String oAuth();\n\n      String oBrien();\n\n      BuilderWithUnprefixedGetters<T> build();\n    }\n  }\n\n  @Test\n  public void testBuilderWithUnprefixedGetter() {\n    ImmutableList<String> names = ImmutableList.of(\"fred\", \"jim\");\n    int[] ints = {6, 28, 496, 8128, 33550336};\n    int noGetter = -1;\n\n    BuilderWithUnprefixedGetters.Builder<String> builder = BuilderWithUnprefixedGetters.builder();\n    assertNull(builder.t());\n    try {\n      builder.list();\n      fail(\"Attempt to retrieve unset list property should have failed\");\n    } catch (IllegalStateException e) {\n      if (omitIdentifiers) {\n        assertThat(e).hasMessageThat().isNull();\n      } else {\n        assertThat(e).hasMessageThat().isEqualTo(\"Property \\\"list\\\" has not been set\");\n      }\n    }\n    try {\n      builder.ints();\n      fail(\"Attempt to retrieve unset ints property should have failed\");\n    } catch (IllegalStateException e) {\n      if (omitIdentifiers) {\n        assertThat(e).hasMessageThat().isNull();\n      } else {\n        assertThat(e).hasMessageThat().isEqualTo(\"Property \\\"ints\\\" has not been set\");\n      }\n    }\n\n    builder.setList(names);\n    assertThat(builder.list()).isSameInstanceAs(names);\n    builder.setInts(ints);\n    assertThat(builder.ints()).isEqualTo(ints);\n    builder.setoAuth(\"OAuth\");\n    assertThat(builder.oAuth()).isEqualTo(\"OAuth\");\n    builder.setOBrien(\"Flann\");\n    assertThat(builder.oBrien()).isEqualTo(\"Flann\");\n    // The array is not cloned by the getter, so the client can modify it (but shouldn't).\n    ints[0] = 0;\n    assertThat(builder.ints()[0]).isEqualTo(0);\n    ints[0] = 6;\n\n    BuilderWithUnprefixedGetters<String> instance = builder.setNoGetter(noGetter).build();\n    assertThat(instance.list()).isSameInstanceAs(names);\n    assertThat(instance.t()).isNull();\n    assertThat(instance.ints()).isEqualTo(ints);\n    assertThat(instance.noGetter()).isEqualTo(noGetter);\n    assertThat(instance.oAuth()).isEqualTo(\"OAuth\");\n    assertThat(instance.oBrien()).isEqualTo(\"Flann\");\n  }\n\n  @AutoValue\n  public abstract static class BuilderWithPrefixedGetters<T extends Comparable<T>> {\n    public abstract ImmutableList<T> getList();\n\n    public abstract T getT();\n\n    @SuppressWarnings(\"mutable\")\n    @Nullable\n    public abstract int[] getInts();\n\n    public abstract ImmutableList<String> getOAuths();\n\n    public abstract int getNoGetter();\n\n    public static <T extends Comparable<T>> Builder<T> builder() {\n      return new AutoValue_AutoValueTest_BuilderWithPrefixedGetters.Builder<T>();\n    }\n\n    @AutoValue.Builder\n    public abstract static class Builder<T extends Comparable<T>> {\n      public abstract Builder<T> setList(ImmutableList<T> list);\n\n      public abstract Builder<T> setT(T t);\n\n      public abstract Builder<T> setInts(int[] ints);\n\n      public abstract Builder<T> setNoGetter(int x);\n\n      public abstract Builder<T> setOAuths(List<String> x);\n\n      public abstract ImmutableList.Builder<String> oAuthsBuilder();\n\n      abstract ImmutableList<T> getList();\n\n      abstract T getT();\n\n      abstract int[] getInts();\n\n      public abstract BuilderWithPrefixedGetters<T> build();\n    }\n  }\n\n  @Test\n  public void testBuilderWithPrefixedGetter() {\n    ImmutableList<String> names = ImmutableList.of(\"fred\", \"jim\");\n    String name = \"sheila\";\n    int noGetter = -1;\n\n    BuilderWithPrefixedGetters.Builder<String> builder = BuilderWithPrefixedGetters.builder();\n    assertThat(builder.getInts()).isNull();\n    try {\n      builder.getList();\n      fail(\"Attempt to retrieve unset list property should have failed\");\n    } catch (IllegalStateException e) {\n      if (omitIdentifiers) {\n        assertThat(e).hasMessageThat().isNull();\n      } else {\n        assertThat(e).hasMessageThat().isEqualTo(\"Property \\\"list\\\" has not been set\");\n      }\n    }\n\n    builder.setList(names);\n    assertThat(builder.getList()).isSameInstanceAs(names);\n    builder.setT(name);\n    assertThat(builder.getInts()).isNull();\n    builder.setOAuths(ImmutableList.of(\"OAuth\"));\n\n    BuilderWithPrefixedGetters<String> instance = builder.setNoGetter(noGetter).build();\n    assertThat(instance.getList()).isSameInstanceAs(names);\n    assertThat(instance.getT()).isEqualTo(name);\n    assertThat(instance.getInts()).isNull();\n    assertThat(instance.getNoGetter()).isEqualTo(noGetter);\n    assertThat(instance.getOAuths()).containsExactly(\"OAuth\");\n\n    builder =\n        BuilderWithPrefixedGetters.<String>builder()\n            .setList(names)\n            .setT(name)\n            .setNoGetter(noGetter);\n    builder.oAuthsBuilder().add(\"foo\", \"bar\");\n    assertThat(builder.build().getOAuths()).containsExactly(\"foo\", \"bar\").inOrder();\n  }\n\n  @AutoValue\n  public abstract static class BuilderWithPrefixedGettersAndUnprefixedSetters {\n    public abstract String getOAuth();\n\n    public abstract String getOBrien();\n\n    public static Builder builder() {\n      return new AutoValue_AutoValueTest_BuilderWithPrefixedGettersAndUnprefixedSetters.Builder();\n    }\n\n    @AutoValue.Builder\n    public abstract static class Builder {\n      public abstract Builder oAuth(String x);\n\n      public abstract Builder OBrien(String x);\n\n      public abstract BuilderWithPrefixedGettersAndUnprefixedSetters build();\n    }\n  }\n\n  @Test\n  public void testBuilderWithPrefixedGetterAndUnprefixedSetter() {\n    BuilderWithPrefixedGettersAndUnprefixedSetters x =\n        BuilderWithPrefixedGettersAndUnprefixedSetters.builder()\n            .oAuth(\"OAuth\")\n            .OBrien(\"Flann\")\n            .build();\n    assertThat(x.getOAuth()).isEqualTo(\"OAuth\");\n    assertThat(x.getOBrien()).isEqualTo(\"Flann\");\n  }\n\n  @AutoValue\n  public abstract static class BuilderWithPropertyBuilders<FooT extends Comparable<FooT>> {\n    public abstract ImmutableList<FooT> getFoos();\n\n    public abstract ImmutableSet<String> getStrings();\n\n    public abstract BuilderWithPropertyBuilders.Builder<FooT> toBuilder();\n\n    public static <FooT extends Comparable<FooT>> Builder<FooT> builder() {\n      return new AutoValue_AutoValueTest_BuilderWithPropertyBuilders.Builder<FooT>();\n    }\n\n    @AutoValue.Builder\n    public abstract static class Builder<FooT extends Comparable<FooT>> {\n      public abstract ImmutableList<FooT> getFoos();\n\n      public Builder<FooT> addFoos(Iterable<FooT> foos) {\n        foosBuilder().addAll(foos);\n        return this;\n      }\n\n      abstract ImmutableList.Builder<FooT> foosBuilder();\n\n      public Builder<FooT> addToTs(FooT element) {\n        foosBuilder().add(element);\n        return this;\n      }\n\n      abstract Builder<FooT> setStrings(ImmutableList<String> strings);\n\n      abstract ImmutableSet.Builder<String> stringsBuilder();\n\n      public Builder<FooT> addToStrings(String element) {\n        stringsBuilder().add(element);\n        return this;\n      }\n\n      public abstract BuilderWithPropertyBuilders<FooT> build();\n    }\n  }\n\n  @Test\n  public void testBuilderWithPropertyBuilders() {\n    ImmutableList<Integer> numbers = ImmutableList.of(1, 1, 2, 6, 24);\n    ImmutableSet<String> names = ImmutableSet.of(\"one\", \"two\", \"six\", \"twenty-four\");\n\n    BuilderWithPropertyBuilders<Integer> a =\n        BuilderWithPropertyBuilders.<Integer>builder()\n            .addFoos(numbers)\n            .addToStrings(\"one\")\n            .addToStrings(\"two\")\n            .addToStrings(\"six\")\n            .addToStrings(\"twenty-four\")\n            .build();\n\n    assertEquals(numbers, a.getFoos());\n    assertEquals(names, a.getStrings());\n\n    BuilderWithPropertyBuilders.Builder<Integer> bBuilder = BuilderWithPropertyBuilders.builder();\n    bBuilder.stringsBuilder().addAll(names);\n    bBuilder.foosBuilder().addAll(numbers);\n\n    assertEquals(numbers, bBuilder.getFoos());\n\n    BuilderWithPropertyBuilders<Integer> b = bBuilder.build();\n    assertEquals(a, b);\n\n    BuilderWithPropertyBuilders.Builder<Integer> cBuilder = a.toBuilder();\n    cBuilder.addToStrings(\"one hundred and twenty\");\n    cBuilder.addToTs(120);\n    BuilderWithPropertyBuilders<Integer> c = cBuilder.build();\n    assertEquals(\n        ImmutableSet.of(\"one\", \"two\", \"six\", \"twenty-four\", \"one hundred and twenty\"),\n        c.getStrings());\n    assertEquals(ImmutableList.of(1, 1, 2, 6, 24, 120), c.getFoos());\n\n    BuilderWithPropertyBuilders.Builder<Integer> dBuilder = a.toBuilder();\n    dBuilder.addFoos(ImmutableList.of(120, 720));\n    BuilderWithPropertyBuilders<Integer> d = dBuilder.build();\n    assertEquals(ImmutableList.of(1, 1, 2, 6, 24, 120, 720), d.getFoos());\n    assertEquals(names, d.getStrings());\n\n    BuilderWithPropertyBuilders<Integer> empty =\n        BuilderWithPropertyBuilders.<Integer>builder().build();\n    assertEquals(ImmutableList.of(), empty.getFoos());\n    assertEquals(ImmutableSet.of(), empty.getStrings());\n\n    try {\n      BuilderWithPropertyBuilders.<Integer>builder().setStrings(null).build();\n      fail(\"Did not get expected exception\");\n    } catch (RuntimeException expected) {\n      // We don't specify whether you get the exception on setStrings(null) or on build(), nor\n      // which exception it is exactly.\n    }\n  }\n\n  interface ImmutableListOf<T> {\n    ImmutableList<T> list();\n  }\n\n  @AutoValue\n  abstract static class PropertyBuilderInheritsType implements ImmutableListOf<String> {\n    static Builder builder() {\n      return new AutoValue_AutoValueTest_PropertyBuilderInheritsType.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder {\n      abstract ImmutableList.Builder<String> listBuilder();\n\n      abstract PropertyBuilderInheritsType build();\n    }\n  }\n\n  @Test\n  public void propertyBuilderInheritsType() {\n    PropertyBuilderInheritsType.Builder builder = PropertyBuilderInheritsType.builder();\n    builder.listBuilder().add(\"foo\", \"bar\");\n    PropertyBuilderInheritsType x = builder.build();\n    assertThat(x.list()).containsExactly(\"foo\", \"bar\").inOrder();\n  }\n\n  @AutoValue\n  public abstract static class BuilderWithExoticPropertyBuilders<\n      K extends Number, V extends Comparable<K>> {\n    public abstract ImmutableMap<String, V> map();\n\n    public abstract ImmutableTable<String, K, V> table();\n\n    public static <K extends Number, V extends Comparable<K>> Builder<K, V> builder() {\n      return new AutoValue_AutoValueTest_BuilderWithExoticPropertyBuilders.Builder<K, V>();\n    }\n\n    @AutoValue.Builder\n    public abstract static class Builder<K extends Number, V extends Comparable<K>> {\n      public Builder<K, V> putAll(Map<String, V> map) {\n        mapBuilder().putAll(map);\n        return this;\n      }\n\n      public abstract ImmutableMap.Builder<String, V> mapBuilder();\n\n      public Builder<K, V> putAll(ImmutableTable<String, K, V> table) {\n        tableBuilder().putAll(table);\n        return this;\n      }\n\n      public abstract ImmutableTable.Builder<String, K, V> tableBuilder();\n\n      public abstract BuilderWithExoticPropertyBuilders<K, V> build();\n    }\n  }\n\n  @Test\n  public void testBuilderWithExoticPropertyBuilders() {\n    ImmutableMap<String, Integer> map = ImmutableMap.of(\"one\", 1);\n    ImmutableTable<String, Integer, Integer> table = ImmutableTable.of(\"one\", 1, -1);\n\n    BuilderWithExoticPropertyBuilders<Integer, Integer> a =\n        BuilderWithExoticPropertyBuilders.<Integer, Integer>builder()\n            .putAll(map)\n            .putAll(table)\n            .build();\n    assertEquals(map, a.map());\n    assertEquals(table, a.table());\n\n    BuilderWithExoticPropertyBuilders.Builder<Integer, Integer> bBuilder =\n        BuilderWithExoticPropertyBuilders.builder();\n    bBuilder.mapBuilder().putAll(map);\n    bBuilder.tableBuilder().putAll(table);\n    BuilderWithExoticPropertyBuilders<Integer, Integer> b = bBuilder.build();\n    assertEquals(a, b);\n\n    BuilderWithExoticPropertyBuilders<Integer, Integer> empty =\n        BuilderWithExoticPropertyBuilders.<Integer, Integer>builder().build();\n    assertEquals(ImmutableMap.of(), empty.map());\n    assertEquals(ImmutableTable.of(), empty.table());\n  }\n\n  @AutoValue\n  public abstract static class BuilderWithCopyingSetters<T extends Number> {\n    public abstract ImmutableSet<? extends T> things();\n\n    public abstract ImmutableList<Number> numbers();\n\n    public abstract ImmutableMap<String, T> map();\n\n    public static <T extends Number> Builder<T> builder(T value) {\n      return new AutoValue_AutoValueTest_BuilderWithCopyingSetters.Builder<T>()\n          .setNumbers(ImmutableSet.of(17, 23.0))\n          .setMap(Collections.singletonMap(\"foo\", value));\n    }\n\n    @AutoValue.Builder\n    public interface Builder<T extends Number> {\n      Builder<T> setThings(ImmutableSet<T> things);\n\n      Builder<T> setThings(Iterable<? extends T> things);\n\n      Builder<T> setThings(T... things);\n\n      Builder<T> setNumbers(Collection<? extends Number> strings);\n\n      Builder<T> setMap(Map<String, T> map);\n\n      BuilderWithCopyingSetters<T> build();\n    }\n  }\n\n  @Test\n  public void testBuilderWithCopyingSetters() {\n    BuilderWithCopyingSetters.Builder<Integer> builder = BuilderWithCopyingSetters.builder(23);\n\n    BuilderWithCopyingSetters<Integer> a = builder.setThings(ImmutableSet.of(1, 2)).build();\n    assertThat(a.things()).containsExactly(1, 2);\n    assertThat(a.numbers()).containsExactly(17, 23.0).inOrder();\n    assertThat(a.map()).containsExactly(\"foo\", 23);\n\n    BuilderWithCopyingSetters<Integer> b = builder.setThings(Arrays.asList(1, 2)).build();\n    assertThat(b).isEqualTo(a);\n\n    BuilderWithCopyingSetters<Integer> c = builder.setThings(1, 2).build();\n    assertThat(c).isEqualTo(a);\n  }\n\n  @AutoValue\n  public abstract static class BuilderWithImmutableSorted<T extends Comparable<T>> {\n    public abstract ImmutableSortedSet<T> sortedSet();\n\n    public abstract ImmutableSortedMap<T, Integer> sortedMap();\n\n    public static <T extends Comparable<T>> Builder<T> builder() {\n      return new AutoValue_AutoValueTest_BuilderWithImmutableSorted.Builder<T>()\n          .setSortedSet(new TreeSet<T>())\n          .setSortedMap(new TreeMap<T, Integer>());\n    }\n\n    @AutoValue.Builder\n    public interface Builder<T extends Comparable<T>> {\n      Builder<T> setSortedSet(T... x);\n\n      Builder<T> setSortedSet(NavigableSet<T> x);\n\n      ImmutableSortedSet.Builder<T> sortedSetBuilder();\n\n      Builder<T> setSortedMap(SortedMap<T, Integer> x);\n\n      Builder<T> setSortedMap(NavigableMap<T, Integer> x);\n\n      ImmutableSortedMap.Builder<T, Integer> sortedMapBuilder();\n\n      BuilderWithImmutableSorted<T> build();\n    }\n  }\n\n  @Test\n  public void testBuilderWithImmutableSorted_Varargs() {\n    BuilderWithImmutableSorted<String> x =\n        BuilderWithImmutableSorted.<String>builder().setSortedSet(\"foo\", \"bar\", \"baz\").build();\n    assertThat(x.sortedSet()).containsExactly(\"bar\", \"baz\", \"foo\").inOrder();\n  }\n\n  @Test\n  public void testBuilderWithImmutableSorted_SetSet() {\n    BuilderWithImmutableSorted<String> x =\n        BuilderWithImmutableSorted.<String>builder()\n            .setSortedSet(new TreeSet<String>(String.CASE_INSENSITIVE_ORDER))\n            .build();\n    assertThat(x.sortedSet().comparator()).isEqualTo(String.CASE_INSENSITIVE_ORDER);\n  }\n\n  @Test\n  public void testBuilderWithImmutableSorted_SetMap() {\n    BuilderWithImmutableSorted<String> x =\n        BuilderWithImmutableSorted.<String>builder()\n            .setSortedMap(new TreeMap<String, Integer>(String.CASE_INSENSITIVE_ORDER))\n            .build();\n    assertThat(x.sortedMap().comparator()).isEqualTo(String.CASE_INSENSITIVE_ORDER);\n  }\n\n  @Test\n  public void testBuilderWithImmutableSorted_SetCollectionBuilder() {\n    BuilderWithImmutableSorted.Builder<String> builder =\n        BuilderWithImmutableSorted.<String>builder();\n    builder.sortedSetBuilder().add(\"is\", \"ea\", \"id\");\n    BuilderWithImmutableSorted<String> x = builder.build();\n    assertThat(x.sortedSet()).containsExactly(\"ea\", \"id\", \"is\").inOrder();\n  }\n\n  @Test\n  public void testBuilderWithImmutableSorted_MapCollectionBuilder() {\n    BuilderWithImmutableSorted.Builder<String> builder =\n        BuilderWithImmutableSorted.<String>builder();\n    builder.sortedMapBuilder().put(\"two\", 2).put(\"one\", 1);\n    BuilderWithImmutableSorted<String> x = builder.build();\n    assertThat(x.sortedMap()).containsExactly(\"one\", 1, \"two\", 2).inOrder();\n  }\n\n  @AutoValue\n  public abstract static class BuilderWithCollectionBuilderAndSetter<T extends Number> {\n    public abstract ImmutableList<T> things();\n\n    public static <T extends Number> Builder<T> builder() {\n      return new AutoValue_AutoValueTest_BuilderWithCollectionBuilderAndSetter.Builder<T>();\n    }\n\n    @AutoValue.Builder\n    public interface Builder<T extends Number> {\n      Builder<T> setThings(List<T> things);\n\n      ImmutableList<T> things();\n\n      ImmutableList.Builder<T> thingsBuilder();\n\n      BuilderWithCollectionBuilderAndSetter<T> build();\n    }\n  }\n\n  @Test\n  public void testBuilderAndSetterDefaultsEmpty() {\n    BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =\n        BuilderWithCollectionBuilderAndSetter.<Integer>builder();\n    assertThat(builder.things()).isEmpty();\n    assertThat(builder.build().things()).isEmpty();\n  }\n\n  @Test\n  public void testBuilderAndSetterUsingBuilder() {\n    BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =\n        BuilderWithCollectionBuilderAndSetter.builder();\n    builder.thingsBuilder().add(17, 23);\n    BuilderWithCollectionBuilderAndSetter<Integer> x = builder.build();\n    assertThat(x.things()).isEqualTo(ImmutableList.of(17, 23));\n  }\n\n  @Test\n  public void testBuilderAndSetterUsingSetter() {\n    ImmutableList<Integer> things = ImmutableList.of(17, 23);\n    BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =\n        BuilderWithCollectionBuilderAndSetter.<Integer>builder().setThings(things);\n    assertThat(builder.things()).isSameInstanceAs(things);\n    assertThat(builder.build().things()).isSameInstanceAs(things);\n\n    List<Integer> moreThings = Arrays.asList(5, 17, 23);\n    BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder2 =\n        BuilderWithCollectionBuilderAndSetter.<Integer>builder().setThings(moreThings);\n    assertThat(builder2.things()).isEqualTo(moreThings);\n    assertThat(builder2.build().things()).isEqualTo(moreThings);\n  }\n\n  @Test\n  public void testBuilderAndSetterUsingSetterThenBuilder() {\n    BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =\n        BuilderWithCollectionBuilderAndSetter.builder();\n    builder.setThings(ImmutableList.of(5));\n    builder.thingsBuilder().add(17, 23);\n    List<Integer> expectedThings = ImmutableList.of(5, 17, 23);\n    assertThat(builder.things()).isEqualTo(expectedThings);\n    assertThat(builder.build().things()).isEqualTo(expectedThings);\n  }\n\n  @Test\n  public void testBuilderAndSetterCannotSetAfterBuilder() {\n    BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =\n        BuilderWithCollectionBuilderAndSetter.builder();\n    builder.setThings(ImmutableList.of(5));\n    builder.thingsBuilder().add(17, 23);\n    try {\n      builder.setThings(ImmutableList.of(1729));\n      fail(\"Setting list after retrieving builder should provoke an exception\");\n    } catch (IllegalStateException e) {\n      if (omitIdentifiers) {\n        assertThat(e).hasMessageThat().isNull();\n      } else {\n        assertThat(e).hasMessageThat().isEqualTo(\"Cannot set things after calling thingsBuilder()\");\n      }\n    }\n  }\n\n  abstract static class AbstractParentWithBuilder {\n    abstract String foo();\n\n    abstract static class Builder<B extends Builder<B>> {\n      abstract B foo(String s);\n    }\n  }\n\n  @AutoValue\n  abstract static class ChildWithBuilder extends AbstractParentWithBuilder {\n    abstract String bar();\n\n    static Builder builder() {\n      return new AutoValue_AutoValueTest_ChildWithBuilder.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder extends AbstractParentWithBuilder.Builder<Builder> {\n      abstract Builder bar(String s);\n\n      abstract ChildWithBuilder build();\n    }\n  }\n\n  @Test\n  public void testInheritedBuilder() {\n    ChildWithBuilder x = ChildWithBuilder.builder().foo(\"foo\").bar(\"bar\").build();\n    assertThat(x.foo()).isEqualTo(\"foo\");\n    assertThat(x.bar()).isEqualTo(\"bar\");\n  }\n\n  @Retention(RetentionPolicy.RUNTIME)\n  @interface GwtCompatible {\n    boolean funky() default false;\n  }\n\n  @AutoValue\n  @GwtCompatible(funky = true)\n  abstract static class GwtCompatibleTest {\n    abstract int foo();\n\n    static GwtCompatibleTest create(int foo) {\n      return new AutoValue_AutoValueTest_GwtCompatibleTest(foo);\n    }\n  }\n\n  @AutoValue\n  @GwtCompatible\n  abstract static class GwtCompatibleTestNoArgs {\n    abstract String bar();\n\n    static GwtCompatibleTestNoArgs create(String bar) {\n      return new AutoValue_AutoValueTest_GwtCompatibleTestNoArgs(bar);\n    }\n  }\n\n  @Test\n  public void testGwtCompatibleInherited() {\n    GwtCompatibleTest test = GwtCompatibleTest.create(23);\n    GwtCompatible gwtCompatible = test.getClass().getAnnotation(GwtCompatible.class);\n    assertNotNull(gwtCompatible);\n    assertTrue(gwtCompatible.funky());\n\n    GwtCompatibleTestNoArgs testNoArgs = GwtCompatibleTestNoArgs.create(\"23\");\n    GwtCompatible gwtCompatibleNoArgs = testNoArgs.getClass().getAnnotation(GwtCompatible.class);\n    assertNotNull(gwtCompatibleNoArgs);\n    assertFalse(gwtCompatibleNoArgs.funky());\n  }\n\n  @interface NestedAnnotation {\n    int anInt();\n\n    Class<?>[] aClassArray();\n  }\n\n  @Retention(RetentionPolicy.RUNTIME)\n  @interface HairyAnnotation {\n    String aString();\n\n    Class<? extends Number> aClass();\n\n    RetentionPolicy anEnum();\n\n    NestedAnnotation anAnnotation();\n  }\n\n  @Retention(RetentionPolicy.RUNTIME)\n  @interface CopiedAnnotation {}\n\n  @Retention(RetentionPolicy.RUNTIME)\n  @interface ExcludedAnnotation {}\n\n  @Retention(RetentionPolicy.RUNTIME)\n  @Inherited\n  @interface InheritedAnnotation {}\n\n  @CopiedAnnotation\n  @ExcludedAnnotation\n  @InheritedAnnotation\n  @AutoValue\n  @AutoValue.CopyAnnotations(exclude = {ExcludedAnnotation.class})\n  abstract static class CopyAnnotation {\n    @HairyAnnotation(\n        aString = \"hello\",\n        aClass = Integer.class,\n        anEnum = RetentionPolicy.RUNTIME,\n        anAnnotation =\n            @NestedAnnotation(\n                anInt = 73,\n                aClassArray = {String.class, Object.class}))\n    abstract String field1();\n\n    @CopiedAnnotation\n    @ExcludedAnnotation\n    @InheritedAnnotation\n    @AutoValue.CopyAnnotations(exclude = {ExcludedAnnotation.class})\n    abstract String field2();\n\n    static CopyAnnotation create() {\n      return new AutoValue_AutoValueTest_CopyAnnotation(\"field1\", \"field2\");\n    }\n  }\n\n  @Test\n  public void testCopyClassAnnotations() throws Exception {\n    CopyAnnotation x = CopyAnnotation.create();\n    Class<?> c = x.getClass();\n    assertNotSame(CopyAnnotation.class, c);\n\n    // Sanity check: if these don't appear on CopyAnnotation, it makes no sense to assert that they\n    // don't appear on the AutoValue_ subclass.\n    {\n      List<Class<? extends Annotation>> annotationsOnSuperclass =\n          new ArrayList<Class<? extends Annotation>>();\n      for (Annotation annotation : CopyAnnotation.class.getDeclaredAnnotations()) {\n        annotationsOnSuperclass.add(annotation.annotationType());\n      }\n      assertThat(annotationsOnSuperclass)\n          .containsAtLeast(\n              CopiedAnnotation.class, ExcludedAnnotation.class, InheritedAnnotation.class);\n    }\n\n    {\n      List<Class<? extends Annotation>> annotationsOnSubclass =\n          new ArrayList<Class<? extends Annotation>>();\n      for (Annotation annotation : c.getDeclaredAnnotations()) {\n        annotationsOnSubclass.add(annotation.annotationType());\n      }\n      assertThat(annotationsOnSubclass).containsExactly(CopiedAnnotation.class);\n    }\n  }\n\n  @Test\n  public void testCopyMethodAnnotations() throws Exception {\n    CopyAnnotation x = CopyAnnotation.create();\n    Class<?> c = x.getClass();\n    assertNotSame(CopyAnnotation.class, c);\n\n    Method methodInSubclass = c.getDeclaredMethod(\"field2\");\n    Method methodInSuperclass = CopyAnnotation.class.getDeclaredMethod(\"field2\");\n\n    // Sanity check: if these don't appear on CopyAnnotation, it makes no sense to assert that they\n    // don't appear on the AutoValue_ subclass.\n    assertThat(methodInSuperclass.isAnnotationPresent(CopiedAnnotation.class)).isTrue();\n    assertThat(methodInSuperclass.isAnnotationPresent(ExcludedAnnotation.class)).isTrue();\n    assertThat(methodInSuperclass.isAnnotationPresent(InheritedAnnotation.class)).isTrue();\n\n    assertThat(methodInSubclass.isAnnotationPresent(CopiedAnnotation.class)).isTrue();\n    assertThat(methodInSubclass.isAnnotationPresent(ExcludedAnnotation.class)).isFalse();\n    assertThat(methodInSubclass.isAnnotationPresent(InheritedAnnotation.class)).isTrue();\n  }\n\n  @Test\n  public void testCopyMethodAnnotationsByDefault() throws Exception {\n    CopyAnnotation x = CopyAnnotation.create();\n    Class<?> c = x.getClass();\n    assertNotSame(CopyAnnotation.class, c);\n    Method methodInSubclass = c.getDeclaredMethod(\"field1\");\n    Method methodInSuperclass = CopyAnnotation.class.getDeclaredMethod(\"field1\");\n    assertNotSame(methodInSuperclass, methodInSubclass);\n    HairyAnnotation annotationInSubclass = methodInSubclass.getAnnotation(HairyAnnotation.class);\n    HairyAnnotation annotationInSuperclass =\n        methodInSuperclass.getAnnotation(HairyAnnotation.class);\n    assertEquals(annotationInSuperclass, annotationInSubclass);\n  }\n\n  @AutoValue\n  abstract static class HProperty {\n    public abstract Object h();\n\n    public static HProperty create(Object h) {\n      return new AutoValue_AutoValueTest_HProperty(h);\n    }\n  }\n\n  @Test\n  public void testHProperty() throws Exception {\n    // Checks that we can have a property called `h`. The generated hashCode() method has\n    // a local variable of that name and can cause the error `int cannot be dereferenced`\n    HProperty.create(new Object());\n  }\n\n  interface Parent1 {\n    int something();\n  }\n\n  interface Parent2 {\n    int something();\n  }\n\n  @AutoValue\n  abstract static class InheritSameMethodTwice implements Parent1, Parent2 {\n    static InheritSameMethodTwice create(int something) {\n      return new AutoValue_AutoValueTest_InheritSameMethodTwice(something);\n    }\n  }\n\n  @Test\n  public void testInheritSameMethodTwice() {\n    InheritSameMethodTwice x = InheritSameMethodTwice.create(23);\n    assertThat(x.something()).isEqualTo(23);\n  }\n\n  // Make sure we behave correctly when we inherit the same method definition from more than\n  // one parent interface. We expect methods to appear in the order they are seen, with parents\n  // preceding children, the superclass of a class preceding interfaces that class implements,\n  // and an interface mentioned earlier in the \"implements\" clause preceding one mentioned later.\n  // https://github.com/google/auto/issues/372\n  interface OneTwoThreeFour {\n    String one();\n\n    String two();\n\n    boolean three();\n\n    long four();\n  }\n\n  interface TwoFour {\n    String two();\n\n    long four();\n  }\n\n  @AutoValue\n  abstract static class OneTwoThreeFourImpl implements OneTwoThreeFour, TwoFour {\n    static OneTwoThreeFourImpl create(String one, String two, boolean three, long four) {\n      return new AutoValue_AutoValueTest_OneTwoThreeFourImpl(one, two, three, four);\n    }\n  }\n\n  @Test\n  public void testOneTwoThreeFour() {\n    OneTwoThreeFour x = OneTwoThreeFourImpl.create(\"one\", \"two\", false, 4);\n    String expectedString =\n        omitIdentifiers\n            ? \"{one, two, false, 4}\"\n            : \"OneTwoThreeFourImpl{one=one, two=two, three=false, four=4}\";\n    assertThat(x.toString()).isEqualTo(expectedString);\n  }\n\n  @AutoValue\n  abstract static class OuterWithBuilder {\n    abstract String foo();\n\n    abstract InnerWithBuilder inner();\n\n    abstract Builder toBuilder();\n\n    static Builder builder() {\n      return new AutoValue_AutoValueTest_OuterWithBuilder.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder {\n      abstract Builder foo(String x);\n\n      abstract Builder inner(InnerWithBuilder x);\n\n      abstract InnerWithBuilder.Builder innerBuilder();\n\n      abstract OuterWithBuilder build();\n    }\n  }\n\n  @AutoValue\n  abstract static class InnerWithBuilder {\n    abstract int bar();\n\n    abstract Builder toBuilder();\n\n    static Builder builder() {\n      return new AutoValue_AutoValueTest_InnerWithBuilder.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder {\n      abstract Builder setBar(int x);\n\n      abstract InnerWithBuilder build();\n    }\n  }\n\n  @Test\n  public void testBuilderWithinBuilder() {\n    OuterWithBuilder x =\n        OuterWithBuilder.builder()\n            .inner(InnerWithBuilder.builder().setBar(23).build())\n            .foo(\"yes\")\n            .build();\n    String expectedStringX =\n        omitIdentifiers\n            ? \"{yes, {23}}\"\n            : \"OuterWithBuilder{foo=yes, inner=InnerWithBuilder{bar=23}}\";\n    assertThat(x.toString()).isEqualTo(expectedStringX);\n\n    OuterWithBuilder.Builder xBuilder = x.toBuilder();\n    xBuilder.innerBuilder().setBar(17);\n    OuterWithBuilder y = xBuilder.build();\n    String expectedStringY =\n        omitIdentifiers\n            ? \"{yes, {17}}\"\n            : \"OuterWithBuilder{foo=yes, inner=InnerWithBuilder{bar=17}}\";\n    assertThat(y.toString()).isEqualTo(expectedStringY);\n  }\n\n  public static class MyMap<K, V> extends HashMap<K, V> {\n    private static final long serialVersionUID = 1L;\n\n    public MyMap() {}\n\n    public MyMap(Map<K, V> map) {\n      super(map);\n    }\n  }\n\n  public static class MyMapBuilder<K, V> extends LinkedHashMap<K, V> {\n    private static final long serialVersionUID = 1L;\n\n    public MyMapBuilder() {}\n\n    public MyMapBuilder(Map<K, V> map) {\n      super(map);\n    }\n\n    public MyMap<K, V> build() {\n      return new MyMap<K, V>(this);\n    }\n  }\n\n  @AutoValue\n  abstract static class BuildMyMap<K, V> {\n    abstract MyMap<K, V> map();\n\n    abstract Builder<K, V> toBuilder();\n\n    static <K, V> Builder<K, V> builder() {\n      return new AutoValue_AutoValueTest_BuildMyMap.Builder<K, V>();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder<K, V> {\n      abstract MyMapBuilder<K, V> mapBuilder();\n\n      abstract BuildMyMap<K, V> build();\n    }\n  }\n\n  @Test\n  public void testMyMapBuilder() {\n    BuildMyMap.Builder<String, Integer> builder = BuildMyMap.builder();\n    MyMapBuilder<String, Integer> mapBuilder = builder.mapBuilder();\n    mapBuilder.put(\"23\", 23);\n    BuildMyMap<String, Integer> built = builder.build();\n    assertThat(built.map()).containsExactly(\"23\", 23);\n\n    BuildMyMap.Builder<String, Integer> builder2 = built.toBuilder();\n    MyMapBuilder<String, Integer> mapBuilder2 = builder2.mapBuilder();\n    mapBuilder2.put(\"17\", 17);\n    BuildMyMap<String, Integer> built2 = builder2.build();\n    assertThat(built2.map()).containsExactly(\"23\", 23, \"17\", 17);\n  }\n\n  public static class MyStringMap<V> extends MyMap<String, V> {\n    private static final long serialVersionUID = 1L;\n\n    public MyStringMap() {}\n\n    public MyStringMap(Map<String, V> map) {\n      super(map);\n    }\n\n    public MyStringMapBuilder<V> toBuilder() {\n      return new MyStringMapBuilder<V>(this);\n    }\n  }\n\n  public static class MyStringMapBuilder<V> extends MyMapBuilder<String, V> {\n    private static final long serialVersionUID = 1L;\n\n    public MyStringMapBuilder() {}\n\n    public MyStringMapBuilder(Map<String, V> map) {\n      super(map);\n    }\n\n    @Override\n    public MyStringMap<V> build() {\n      return new MyStringMap<V>(this);\n    }\n  }\n\n  @AutoValue\n  abstract static class BuildMyStringMap<V> {\n    abstract MyStringMap<V> map();\n\n    abstract Builder<V> toBuilder();\n\n    static <V> Builder<V> builder() {\n      return new AutoValue_AutoValueTest_BuildMyStringMap.Builder<V>();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder<V> {\n      abstract MyStringMapBuilder<V> mapBuilder();\n\n      abstract BuildMyStringMap<V> build();\n    }\n  }\n\n  @Test\n  public void testMyStringMapBuilder() {\n    BuildMyStringMap.Builder<Integer> builder = BuildMyStringMap.builder();\n    MyStringMapBuilder<Integer> mapBuilder = builder.mapBuilder();\n    mapBuilder.put(\"23\", 23);\n    BuildMyStringMap<Integer> built = builder.build();\n    assertThat(built.map()).containsExactly(\"23\", 23);\n\n    BuildMyStringMap.Builder<Integer> builder2 = built.toBuilder();\n    MyStringMapBuilder<Integer> mapBuilder2 = builder2.mapBuilder();\n    mapBuilder2.put(\"17\", 17);\n    BuildMyStringMap<Integer> built2 = builder2.build();\n    assertThat(built2.map()).containsExactly(\"17\", 17, \"23\", 23);\n  }\n\n  @AutoValue\n  abstract static class BuilderOfManyAccessLevels {\n    public abstract int publicGetterProtectedBuilderGetterPackageProtectedSetterInt();\n\n    protected abstract int protectedGetterPackageProtectedBuilderGetterPublicSetterInt();\n\n    abstract int packageProtectedGetterPublicBuilderGetterProtectedSetterInt();\n\n    @AutoValue.Builder\n    public abstract static class Builder {\n      protected abstract int publicGetterProtectedBuilderGetterPackageProtectedSetterInt();\n\n      abstract int protectedGetterPackageProtectedBuilderGetterPublicSetterInt();\n\n      public abstract int packageProtectedGetterPublicBuilderGetterProtectedSetterInt();\n\n      abstract Builder setPublicGetterProtectedBuilderGetterPackageProtectedSetterInt(int x);\n\n      public abstract Builder setProtectedGetterPackageProtectedBuilderGetterPublicSetterInt(int x);\n\n      protected abstract Builder setPackageProtectedGetterPublicBuilderGetterProtectedSetterInt(\n          int x);\n\n      public abstract BuilderOfManyAccessLevels build();\n    }\n  }\n\n  @Test\n  public void testBuilderOfManyAccessLevels_accessLevels() throws NoSuchMethodException {\n    Class<?> builderClass = AutoValue_AutoValueTest_BuilderOfManyAccessLevels.Builder.class;\n\n    testMethodAccess(\n        Access.PROTECTED,\n        builderClass,\n        \"publicGetterProtectedBuilderGetterPackageProtectedSetterInt\");\n    testMethodAccess(\n        Access.PACKAGE,\n        builderClass,\n        \"protectedGetterPackageProtectedBuilderGetterPublicSetterInt\");\n    testMethodAccess(\n        Access.PUBLIC, builderClass, \"packageProtectedGetterPublicBuilderGetterProtectedSetterInt\");\n\n    testMethodAccess(\n        Access.PACKAGE,\n        builderClass,\n        \"setPublicGetterProtectedBuilderGetterPackageProtectedSetterInt\",\n        int.class);\n    testMethodAccess(\n        Access.PUBLIC,\n        builderClass,\n        \"setProtectedGetterPackageProtectedBuilderGetterPublicSetterInt\",\n        int.class);\n    testMethodAccess(\n        Access.PROTECTED,\n        builderClass,\n        \"setPackageProtectedGetterPublicBuilderGetterProtectedSetterInt\",\n        int.class);\n  }\n\n  private enum Access {\n    PRIVATE,\n    PACKAGE,\n    PROTECTED,\n    PUBLIC\n  }\n\n  private static final ImmutableMap<Integer, Access> MODIFIER_BITS_TO_ACCESS =\n      ImmutableMap.of(\n          Modifier.PUBLIC,\n          Access.PUBLIC,\n          Modifier.PROTECTED,\n          Access.PROTECTED,\n          Modifier.PRIVATE,\n          Access.PRIVATE,\n          0,\n          Access.PACKAGE);\n\n  private static void testMethodAccess(\n      Access expectedAccess, Class<?> clazz, String methodName, Class<?>... parameterTypes)\n      throws NoSuchMethodException {\n    Method method = clazz.getDeclaredMethod(methodName, parameterTypes);\n    int modBits = method.getModifiers() & (Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE);\n    Access actualAccess = MODIFIER_BITS_TO_ACCESS.get(modBits);\n    assertWithMessage(\"Wrong access for %s\", methodName)\n        .that(actualAccess)\n        .isEqualTo(expectedAccess);\n  }\n\n  static class VersionId {}\n\n  static class ItemVersionId extends VersionId {}\n\n  interface VersionedPersistent {\n    VersionId getVersionId();\n  }\n\n  interface Item extends VersionedPersistent {\n    @Override\n    ItemVersionId getVersionId();\n  }\n\n  @AutoValue\n  abstract static class FakeItem implements Item {\n    static Builder builder() {\n      return new AutoValue_AutoValueTest_FakeItem.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder {\n      abstract Builder setVersionId(ItemVersionId x);\n\n      abstract FakeItem build();\n    }\n  }\n\n  @Test\n  public void testParentInterfaceOverridesGrandparent() {\n    ItemVersionId version = new ItemVersionId();\n    FakeItem fakeItem = FakeItem.builder().setVersionId(version).build();\n    assertThat(fakeItem.getVersionId()).isSameInstanceAs(version);\n  }\n\n  /** Fake ApkVersionCode class. */\n  public static class ApkVersionCode {}\n\n  /**\n   * Illustrates a potential problem that showed up while generalizing builders. If our imports are\n   * not accurate we may end up importing ImmutableList.Builder, which won't work because the\n   * generated Builder subclass of ReleaseInfoBuilder will supersede it. Normally we wouldn't import\n   * ImmutableList.Builder because the nested Builder class in the {@code @AutoValue} class would\n   * prevent us trying. But in this case the nested class is called ReleaseInfoBuilder so we might\n   * import anyway if we're not careful. This is one reason why we moved away from importing nested\n   * classes to only importing top-level classes.\n   */\n  @AutoValue\n  public abstract static class ReleaseInfo {\n    public static ReleaseInfoBuilder newBuilder() {\n      return new AutoValue_AutoValueTest_ReleaseInfo.Builder();\n    }\n\n    public abstract ImmutableList<ApkVersionCode> apkVersionCodes();\n\n    ReleaseInfo() {}\n\n    /** Notice that this is called ReleaseInfoBuilder and not Builder. */\n    @AutoValue.Builder\n    public abstract static class ReleaseInfoBuilder {\n      public ReleaseInfoBuilder addApkVersionCode(ApkVersionCode code) {\n        apkVersionCodesBuilder().add(code);\n        return this;\n      }\n\n      abstract ImmutableList.Builder<ApkVersionCode> apkVersionCodesBuilder();\n\n      public abstract ReleaseInfo build();\n    }\n  }\n\n  @Test\n  public void testUnusualBuilderName() {\n    ApkVersionCode apkVersionCode = new ApkVersionCode();\n    ReleaseInfo x = ReleaseInfo.newBuilder().addApkVersionCode(apkVersionCode).build();\n    assertThat(x.apkVersionCodes()).containsExactly(apkVersionCode);\n  }\n\n  @AutoValue\n  public abstract static class OuterWithDefaultableInner {\n    public abstract ImmutableList<String> names();\n\n    public abstract DefaultableInner inner();\n\n    public static Builder builder() {\n      return new AutoValue_AutoValueTest_OuterWithDefaultableInner.Builder();\n    }\n\n    @AutoValue.Builder\n    public abstract static class Builder {\n      public abstract ImmutableList<String> names();\n\n      public abstract ImmutableList.Builder<String> namesBuilder();\n\n      public abstract DefaultableInner inner();\n\n      public abstract DefaultableInner.Builder innerBuilder();\n\n      public abstract OuterWithDefaultableInner build();\n    }\n  }\n\n  @AutoValue\n  public abstract static class DefaultableInner {\n    public abstract int bar();\n\n    public static Builder builder() {\n      return new AutoValue_AutoValueTest_DefaultableInner.Builder().setBar(23);\n    }\n\n    @AutoValue.Builder\n    public abstract static class Builder {\n      public abstract Builder setBar(int x);\n\n      public abstract DefaultableInner build();\n    }\n  }\n\n  @Test\n  public void testOuterWithDefaultableInner_Defaults() {\n    DefaultableInner defaultInner = DefaultableInner.builder().build();\n    OuterWithDefaultableInner x = OuterWithDefaultableInner.builder().build();\n    assertThat(x.names()).isEmpty();\n    assertThat(x.inner()).isEqualTo(defaultInner);\n  }\n\n  @Test\n  public void testOuterWithDefaultableInner_Getters() {\n    DefaultableInner defaultInner = DefaultableInner.builder().build();\n\n    OuterWithDefaultableInner.Builder builder = OuterWithDefaultableInner.builder();\n    assertThat(builder.names()).isEmpty();\n    assertThat(builder.inner()).isEqualTo(defaultInner);\n\n    OuterWithDefaultableInner x1 = builder.build();\n    assertThat(x1.names()).isEmpty();\n    assertThat(x1.inner()).isEqualTo(defaultInner);\n\n    builder.namesBuilder().add(\"Fred\");\n    builder.innerBuilder().setBar(17);\n    OuterWithDefaultableInner x2 = builder.build();\n    assertThat(x2.names()).containsExactly(\"Fred\");\n    assertThat(x2.inner().bar()).isEqualTo(17);\n  }\n\n  @AutoValue\n  public abstract static class OuterWithNonDefaultableInner<T> {\n    public abstract int foo();\n\n    public abstract NonDefaultableInner<T> inner();\n\n    public static <T> Builder<T> builder() {\n      return new AutoValue_AutoValueTest_OuterWithNonDefaultableInner.Builder<T>();\n    }\n\n    @AutoValue.Builder\n    public abstract static class Builder<T> {\n      public abstract Builder<T> setFoo(int x);\n\n      public abstract NonDefaultableInner.Builder<T> innerBuilder();\n\n      public abstract OuterWithNonDefaultableInner<T> build();\n    }\n  }\n\n  @AutoValue\n  public abstract static class NonDefaultableInner<E> {\n    public abstract E bar();\n\n    public static <E> Builder<E> builder() {\n      return new AutoValue_AutoValueTest_NonDefaultableInner.Builder<E>();\n    }\n\n    @AutoValue.Builder\n    public abstract static class Builder<E> {\n      public abstract Builder<E> setBar(E x);\n\n      public abstract NonDefaultableInner<E> build();\n    }\n  }\n\n  @Test\n  public void testOuterWithNonDefaultableInner() {\n    OuterWithNonDefaultableInner.Builder<String> builder = OuterWithNonDefaultableInner.builder();\n    builder.setFoo(23);\n    try {\n      builder.build();\n      fail(\"Did not get expected exception for unbuilt inner instance\");\n    } catch (IllegalStateException expected) {\n    }\n  }\n\n  @SuppressWarnings(\"JavaLangClash\")\n  @AutoValue\n  public abstract static class RedeclareJavaLangClasses {\n    // If you really really want to do this, we have you covered.\n\n    public static class Object {}\n\n    public static class String {}\n\n    public abstract Object alienObject();\n\n    public abstract String alienString();\n\n    public static Builder builder() {\n      return new AutoValue_AutoValueTest_RedeclareJavaLangClasses.Builder();\n    }\n\n    @AutoValue.Builder\n    public abstract static class Builder {\n      public abstract Builder setAlienObject(Object x);\n\n      public abstract Builder setAlienString(String x);\n\n      public abstract RedeclareJavaLangClasses build();\n    }\n  }\n\n  @Test\n  public void testRedeclareJavaLangClasses() {\n    RedeclareJavaLangClasses x =\n        RedeclareJavaLangClasses.builder()\n            .setAlienObject(new RedeclareJavaLangClasses.Object())\n            .setAlienString(new RedeclareJavaLangClasses.String())\n            .build();\n    assertThat(x).isNotNull();\n  }\n\n  // b/28382293\n  @AutoValue\n  abstract static class GenericExtends {\n    abstract ImmutableSet<Number> metrics();\n\n    static Builder builder() {\n      return new AutoValue_AutoValueTest_GenericExtends.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder {\n      abstract Builder setMetrics(ImmutableSet<? extends Number> metrics);\n\n      abstract GenericExtends build();\n    }\n  }\n\n  @Test\n  public void testGenericExtends() {\n    ImmutableSet<Integer> ints = ImmutableSet.of(1, 2, 3);\n    GenericExtends g = GenericExtends.builder().setMetrics(ints).build();\n    assertThat(g.metrics()).isEqualTo(ints);\n  }\n\n  abstract static class Parent<T> {\n    abstract List<T> getList();\n  }\n\n  @AutoValue\n  abstract static class Child extends Parent<String> {\n    static Builder builder() {\n      return new AutoValue_AutoValueTest_Child.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder {\n      abstract Builder setList(List<String> list);\n\n      abstract Child build();\n    }\n  }\n\n  @Test\n  public void nonGenericExtendsGeneric() {\n    List<String> list = ImmutableList.of(\"foo\", \"bar\", \"baz\");\n    Child child = Child.builder().setList(list).build();\n    assertThat(child.getList()).containsExactlyElementsIn(list).inOrder();\n  }\n\n  abstract static class AbstractGenericParentWithBuilder<T> {\n    abstract T foo();\n\n    abstract static class Builder<T, B extends Builder<T, B>> {\n      abstract B foo(T s);\n    }\n  }\n\n  @AutoValue\n  abstract static class ChildOfAbstractGenericParentWithBuilder<T>\n      extends AbstractGenericParentWithBuilder<T> {\n    static <T> Builder<T> builder() {\n      return new AutoValue_AutoValueTest_ChildOfAbstractGenericParentWithBuilder.Builder<T>();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder<T>\n        extends AbstractGenericParentWithBuilder.Builder<T, Builder<T>> {\n      abstract ChildOfAbstractGenericParentWithBuilder<T> build();\n    }\n  }\n\n  @Test\n  public void genericExtendsGeneric() {\n    ChildOfAbstractGenericParentWithBuilder<String> child =\n        ChildOfAbstractGenericParentWithBuilder.<String>builder().foo(\"foo\").build();\n    assertThat(child.foo()).isEqualTo(\"foo\");\n  }\n\n  @SuppressWarnings(\"ClassCanBeStatic\")\n  static class OuterWithTypeParam<T extends Number> {\n    class InnerWithTypeParam<U> {}\n\n    class InnerWithoutTypeParam {}\n\n    static class Nested {}\n  }\n\n  @AutoValue\n  abstract static class Nesty {\n    abstract OuterWithTypeParam<Double>.InnerWithTypeParam<String> innerWithTypeParam();\n\n    abstract OuterWithTypeParam<Double>.InnerWithoutTypeParam innerWithoutTypeParam();\n\n    abstract OuterWithTypeParam.Nested nested();\n\n    static Builder builder() {\n      return new AutoValue_AutoValueTest_Nesty.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder {\n      abstract Builder setInnerWithTypeParam(\n          OuterWithTypeParam<Double>.InnerWithTypeParam<String> x);\n\n      abstract Builder setInnerWithoutTypeParam(OuterWithTypeParam<Double>.InnerWithoutTypeParam x);\n\n      abstract Builder setNested(OuterWithTypeParam.Nested x);\n\n      abstract Nesty build();\n    }\n  }\n\n  @Test\n  public void outerWithTypeParam() throws ReflectiveOperationException {\n    @SuppressWarnings(\"UseDiamond\") // Currently we compile this with -source 6 in the Eclipse test.\n    OuterWithTypeParam<Double> outer = new OuterWithTypeParam<Double>();\n    Nesty nesty =\n        Nesty.builder()\n            .setInnerWithTypeParam(outer.new InnerWithTypeParam<String>())\n            .setInnerWithoutTypeParam(outer.new InnerWithoutTypeParam())\n            .setNested(new OuterWithTypeParam.Nested())\n            .build();\n    Type originalReturnType =\n        Nesty.class.getDeclaredMethod(\"innerWithTypeParam\").getGenericReturnType();\n    Type generatedReturnType =\n        nesty.getClass().getDeclaredMethod(\"innerWithTypeParam\").getGenericReturnType();\n    assertThat(generatedReturnType).isEqualTo(originalReturnType);\n    Type generatedBuilderParamType =\n        Nesty.builder()\n            .getClass()\n            .getDeclaredMethod(\"setInnerWithTypeParam\", OuterWithTypeParam.InnerWithTypeParam.class)\n            .getGenericParameterTypes()[0];\n    assertThat(generatedBuilderParamType).isEqualTo(originalReturnType);\n  }\n\n  @AutoValue\n  abstract static class BuilderAnnotationsNotCopied {\n    abstract String foo();\n\n    static Builder builder() {\n      return new AutoValue_AutoValueTest_BuilderAnnotationsNotCopied.Builder();\n    }\n\n    @AutoValue.Builder\n    @MyAnnotation(\"thing\")\n    abstract static class Builder {\n      abstract Builder setFoo(String x);\n\n      abstract BuilderAnnotationsNotCopied build();\n    }\n  }\n\n  @Test\n  public void builderAnnotationsNotCopiedByDefault() {\n    BuilderAnnotationsNotCopied.Builder builder = BuilderAnnotationsNotCopied.builder();\n    assertThat(builder.getClass().getAnnotations()).isEmpty();\n    assertThat(builder.setFoo(\"foo\").build().foo()).isEqualTo(\"foo\");\n  }\n\n  @AutoValue\n  abstract static class BuilderAnnotationsCopied {\n    abstract String foo();\n\n    static Builder builder() {\n      return new AutoValue_AutoValueTest_BuilderAnnotationsCopied.Builder();\n    }\n\n    @AutoValue.Builder\n    @AutoValue.CopyAnnotations\n    @MyAnnotation(\"thing\")\n    abstract static class Builder {\n      abstract Builder setFoo(String x);\n\n      abstract BuilderAnnotationsCopied build();\n    }\n  }\n\n  @Test\n  public void builderAnnotationsCopiedIfRequested() {\n    BuilderAnnotationsCopied.Builder builder = BuilderAnnotationsCopied.builder();\n    assertThat(builder.getClass().getAnnotations()).asList().containsExactly(myAnnotation(\"thing\"));\n    assertThat(builder.setFoo(\"foo\").build().foo()).isEqualTo(\"foo\");\n  }\n\n  @AutoValue\n  @AutoValue.CopyAnnotations\n  @SuppressWarnings({\"rawtypes\", \"unchecked\"}) // deliberately checking handling of raw types\n  abstract static class DataWithSortedCollectionBuilders<K, V> {\n    abstract ImmutableSortedMap<K, V> anImmutableSortedMap();\n\n    abstract ImmutableSortedSet<V> anImmutableSortedSet();\n\n    abstract ImmutableSortedMap<Integer, V> nonGenericImmutableSortedMap();\n\n    abstract ImmutableSortedSet rawImmutableSortedSet();\n\n    abstract DataWithSortedCollectionBuilders.Builder<K, V> toBuilder();\n\n    static <K, V> DataWithSortedCollectionBuilders.Builder<K, V> builder() {\n      return new AutoValue_AutoValueTest_DataWithSortedCollectionBuilders.Builder<K, V>();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder<K, V> {\n      abstract DataWithSortedCollectionBuilders.Builder<K, V> anImmutableSortedMap(\n          SortedMap<K, V> anImmutableSortedMap);\n\n      abstract ImmutableSortedMap.Builder<K, V> anImmutableSortedMapBuilder(\n          Comparator<K> keyComparator);\n\n      abstract DataWithSortedCollectionBuilders.Builder<K, V> anImmutableSortedSet(\n          SortedSet<V> anImmutableSortedSet);\n\n      abstract ImmutableSortedSet.Builder<V> anImmutableSortedSetBuilder(Comparator<V> comparator);\n\n      abstract ImmutableSortedMap.Builder<Integer, V> nonGenericImmutableSortedMapBuilder(\n          Comparator<Integer> keyComparator);\n\n      abstract ImmutableSortedSet.Builder rawImmutableSortedSetBuilder(Comparator comparator);\n\n      abstract DataWithSortedCollectionBuilders<K, V> build();\n    }\n  }\n\n  @Test\n  @SuppressWarnings({\"rawtypes\", \"unchecked\"}) // deliberately checking handling of raw types\n  public void shouldGenerateBuildersWithComparators() {\n    Comparator<String> stringComparator =\n        new Comparator<String>() {\n          @Override\n          public int compare(String left, String right) {\n            return left.compareTo(right);\n          }\n        };\n\n    Comparator<Integer> intComparator =\n        new Comparator<Integer>() {\n          @Override\n          public int compare(Integer o1, Integer o2) {\n            return o1 - o2;\n          }\n        };\n\n    Comparator comparator =\n        new Comparator() {\n          @Override\n          public int compare(Object left, Object right) {\n            return String.valueOf(left).compareTo(String.valueOf(right));\n          }\n        };\n\n    AutoValueTest.DataWithSortedCollectionBuilders.Builder<String, Integer> builder =\n        AutoValueTest.DataWithSortedCollectionBuilders.builder();\n\n    builder\n        .anImmutableSortedMapBuilder(stringComparator)\n        .put(\"Charlie\", 1)\n        .put(\"Alfa\", 2)\n        .put(\"Bravo\", 3);\n    builder.anImmutableSortedSetBuilder(intComparator).add(1, 5, 9, 3);\n    builder.nonGenericImmutableSortedMapBuilder(intComparator).put(9, 99).put(1, 11).put(3, 33);\n    builder.rawImmutableSortedSetBuilder(comparator).add(\"Bravo\", \"Charlie\", \"Alfa\");\n\n    AutoValueTest.DataWithSortedCollectionBuilders<String, Integer> data = builder.build();\n\n    AutoValueTest.DataWithSortedCollectionBuilders.Builder<String, Integer> copiedBuilder =\n        data.toBuilder();\n    AutoValueTest.DataWithSortedCollectionBuilders<String, Integer> copiedData =\n        copiedBuilder.build();\n\n    assertThat(data.anImmutableSortedMap().keySet())\n        .containsExactly(\"Alfa\", \"Bravo\", \"Charlie\")\n        .inOrder();\n    assertThat(data.anImmutableSortedSet()).containsExactly(1, 3, 5, 9).inOrder();\n    assertThat(data.nonGenericImmutableSortedMap().keySet()).containsExactly(1, 3, 9).inOrder();\n    assertThat(data.rawImmutableSortedSet()).containsExactly(\"Alfa\", \"Bravo\", \"Charlie\").inOrder();\n\n    assertThat(copiedData).isEqualTo(data);\n\n    try {\n      builder.anImmutableSortedMapBuilder(Ordering.from(stringComparator).reverse());\n      fail(\"Calling property builder method a second time should have failed\");\n    } catch (IllegalStateException expected) {\n    }\n  }\n\n  @AutoValue\n  public abstract static class Stepped {\n    public abstract String one();\n\n    public abstract int two();\n\n    public abstract double three();\n\n    public interface StepOne<T> {\n      StepTwo setOne(T x);\n    }\n\n    public interface StepTwo {\n      StepThree setTwo(int x);\n    }\n\n    public interface StepThree {\n      Stepped setThreeAndBuild(double x);\n    }\n\n    public static StepOne<String> builder() {\n      return new AutoValue_AutoValueTest_Stepped.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder implements StepOne<String>, StepTwo, StepThree {\n      abstract Builder setThree(double x);\n\n      abstract Stepped build();\n\n      @Override\n      public Stepped setThreeAndBuild(double x) {\n        return setThree(x).build();\n      }\n    }\n  }\n\n  @Test\n  public void stepBuilder() {\n    Stepped stepped = Stepped.builder().setOne(\"one\").setTwo(2).setThreeAndBuild(3.0);\n    assertThat(stepped.one()).isEqualTo(\"one\");\n    assertThat(stepped.two()).isEqualTo(2);\n    assertThat(stepped.three()).isEqualTo(3.0);\n  }\n\n  // The code for tracking unset properties with bitmasks is fairly tricky. When there are many\n  // properties, we use as many ints as needed to track which properties are still unset, with\n  // 32 properties being tracked per int. So here we test @AutoValue classes with 31, 32, and 33\n  // required properties, to catch problems at these edge values that we wouldn't see in our smaller\n  // test classes.\n  abstract static class Giant {\n    abstract int x1();\n\n    abstract int x2();\n\n    abstract int x3();\n\n    abstract int x4();\n\n    abstract int x5();\n\n    abstract int x6();\n\n    abstract int x7();\n\n    abstract int x8();\n\n    abstract int x9();\n\n    abstract int x10();\n\n    abstract int x11();\n\n    abstract int x12();\n\n    abstract int x13();\n\n    abstract int x14();\n\n    abstract int x15();\n\n    abstract int x16();\n\n    abstract int x17();\n\n    abstract int x18();\n\n    abstract int x19();\n\n    abstract int x20();\n\n    abstract int x21();\n\n    abstract int x22();\n\n    abstract int x23();\n\n    abstract int x24();\n\n    abstract int x25();\n\n    abstract int x26();\n\n    abstract int x27();\n\n    abstract int x28();\n\n    abstract int x29();\n\n    abstract int x30();\n\n    abstract int x31();\n\n    abstract static class Builder {\n      abstract Builder x1(int x);\n\n      abstract Builder x2(int x);\n\n      abstract Builder x3(int x);\n\n      abstract Builder x4(int x);\n\n      abstract Builder x5(int x);\n\n      abstract Builder x6(int x);\n\n      abstract Builder x7(int x);\n\n      abstract Builder x8(int x);\n\n      abstract Builder x9(int x);\n\n      abstract Builder x10(int x);\n\n      abstract Builder x11(int x);\n\n      abstract Builder x12(int x);\n\n      abstract Builder x13(int x);\n\n      abstract Builder x14(int x);\n\n      abstract Builder x15(int x);\n\n      abstract Builder x16(int x);\n\n      abstract Builder x17(int x);\n\n      abstract Builder x18(int x);\n\n      abstract Builder x19(int x);\n\n      abstract Builder x20(int x);\n\n      abstract Builder x21(int x);\n\n      abstract Builder x22(int x);\n\n      abstract Builder x23(int x);\n\n      abstract Builder x24(int x);\n\n      abstract Builder x25(int x);\n\n      abstract Builder x26(int x);\n\n      abstract Builder x27(int x);\n\n      abstract Builder x28(int x);\n\n      abstract Builder x29(int x);\n\n      abstract Builder x30(int x);\n\n      abstract Builder x31(int x);\n\n      Builder setFirst30() {\n        return this.x1(1)\n            .x2(2)\n            .x3(3)\n            .x4(4)\n            .x5(5)\n            .x6(6)\n            .x7(7)\n            .x8(8)\n            .x9(9)\n            .x10(10)\n            .x11(11)\n            .x12(12)\n            .x13(13)\n            .x14(14)\n            .x15(15)\n            .x16(16)\n            .x17(17)\n            .x18(18)\n            .x19(19)\n            .x20(20)\n            .x21(21)\n            .x22(22)\n            .x23(23)\n            .x24(24)\n            .x25(25)\n            .x26(26)\n            .x27(27)\n            .x28(28)\n            .x29(29)\n            .x30(30);\n      }\n    }\n  }\n\n  @AutoValue\n  abstract static class Giant31 extends Giant {\n    static Builder builder() {\n      return new AutoValue_AutoValueTest_Giant31.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder extends Giant.Builder {\n      abstract Giant31 build();\n    }\n  }\n\n  @AutoValue\n  abstract static class Giant32 extends Giant {\n    abstract int x32();\n\n    static Builder builder() {\n      return new AutoValue_AutoValueTest_Giant32.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder extends Giant.Builder {\n      abstract Builder x32(int x);\n\n      abstract Giant32 build();\n    }\n  }\n\n  @AutoValue\n  abstract static class Giant33 extends Giant {\n    abstract int x32();\n\n    abstract int x33();\n\n    static Builder builder() {\n      return new AutoValue_AutoValueTest_Giant33.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder extends Giant.Builder {\n      abstract Builder x32(int x);\n\n      abstract Builder x33(int x);\n\n      abstract Giant33 build();\n    }\n  }\n\n  @Test\n  public void testGiant31() {\n    Giant31.Builder builder = Giant31.builder();\n    builder.setFirst30();\n    builder.x31(31);\n    Giant31 giant = builder.build();\n    assertThat(giant.x1()).isEqualTo(1);\n    assertThat(giant.x31()).isEqualTo(31);\n\n    builder = Giant31.builder();\n    builder.setFirst30();\n    try {\n      builder.build();\n      fail();\n    } catch (IllegalStateException expected) {\n      if (omitIdentifiers) {\n        assertThat(expected).hasMessageThat().isNull();\n      } else {\n        assertThat(expected).hasMessageThat().contains(\"x31\");\n        assertThat(expected).hasMessageThat().doesNotContain(\"x30\");\n      }\n    }\n  }\n\n  @Test\n  public void testGiant32() {\n    Giant32.Builder builder = Giant32.builder();\n    builder.setFirst30();\n    builder.x31(31);\n    builder.x32(32);\n    Giant32 giant = builder.build();\n    assertThat(giant.x1()).isEqualTo(1);\n    assertThat(giant.x31()).isEqualTo(31);\n\n    builder = Giant32.builder();\n    builder.setFirst30();\n    try {\n      builder.build();\n      fail();\n    } catch (IllegalStateException expected) {\n      if (omitIdentifiers) {\n        assertThat(expected).hasMessageThat().isNull();\n      } else {\n        assertThat(expected).hasMessageThat().contains(\"x31\");\n        assertThat(expected).hasMessageThat().contains(\"x32\");\n        assertThat(expected).hasMessageThat().doesNotContain(\"x30\");\n      }\n    }\n  }\n\n  @Test\n  public void testGiant33() {\n    Giant33.Builder builder = Giant33.builder();\n    builder.setFirst30();\n    builder.x31(31);\n    builder.x32(32);\n    builder.x33(33);\n    Giant33 giant = builder.build();\n    assertThat(giant.x1()).isEqualTo(1);\n    assertThat(giant.x31()).isEqualTo(31);\n    assertThat(giant.x32()).isEqualTo(32);\n    assertThat(giant.x33()).isEqualTo(33);\n\n    builder = Giant33.builder();\n    builder.setFirst30();\n    try {\n      builder.build();\n      fail();\n    } catch (IllegalStateException expected) {\n      if (omitIdentifiers) {\n        assertThat(expected).hasMessageThat().isNull();\n      } else {\n        assertThat(expected).hasMessageThat().contains(\"x31\");\n        assertThat(expected).hasMessageThat().contains(\"x32\");\n        assertThat(expected).hasMessageThat().contains(\"x33\");\n        assertThat(expected).hasMessageThat().doesNotContain(\"x30\");\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/CompileWithEclipseTest.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value;\n\nimport static com.google.common.base.StandardSystemProperty.JAVA_HOME;\nimport static com.google.common.collect.ImmutableSet.toImmutableSet;\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.common.truth.Truth.assertWithMessage;\n\nimport com.google.auto.value.processor.AutoAnnotationProcessor;\nimport com.google.auto.value.processor.AutoBuilderProcessor;\nimport com.google.auto.value.processor.AutoOneOfProcessor;\nimport com.google.auto.value.processor.AutoValueProcessor;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.function.Predicate;\nimport java.util.stream.Stream;\nimport javax.annotation.processing.Processor;\nimport javax.tools.JavaCompiler;\nimport javax.tools.JavaFileObject;\nimport javax.tools.StandardJavaFileManager;\nimport javax.tools.StandardLocation;\nimport org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;\nimport org.junit.BeforeClass;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.rules.TemporaryFolder;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * Tests that we can compile our AutoValue tests using the Eclipse batch compiler. Since the tests\n * exercise many AutoValue subtleties, the ability to compile them all is a good indication of\n * Eclipse support.\n */\n@RunWith(JUnit4.class)\npublic class CompileWithEclipseTest {\n  private static final String SOURCE_ROOT = System.getProperty(\"basedir\");\n\n  @BeforeClass\n  public static void setSourceRoot() {\n    assertWithMessage(\"basedir property must be set - test must be run from Maven\")\n        .that(SOURCE_ROOT)\n        .isNotNull();\n  }\n\n  public @Rule TemporaryFolder tmp = new TemporaryFolder();\n\n  private static final ImmutableSet<String> IGNORED_TEST_FILES =\n      ImmutableSet.of(\n          \"AutoValueNotEclipseTest.java\",\n          \"CompileWithEclipseTest.java\",\n          \"CustomFieldSerializerTest.java\",\n          \"GradleIT.java\",\n\n          // AutoBuilder sometimes needs to generate a .class file for Kotlin that is used in the\n          // rest of compilation, and Eclipse doesn't seem to handle that well. Presumably not many\n          // Kotlin users use Eclipse since IntelliJ is obviously much more suitable.\n          \"AutoBuilderKotlinTest.java\");\n\n  private static final Predicate<File> JAVA_FILE =\n      f -> f.getName().endsWith(\".java\") && !IGNORED_TEST_FILES.contains(f.getName());\n\n  @Test\n  public void compileWithEclipse() throws IOException {\n    String version = \"8\";\n    File sourceRootFile = new File(SOURCE_ROOT);\n    File javaDir = new File(sourceRootFile, \"src/main/java\");\n    File javatestsDir = new File(sourceRootFile, \"src/test/java\");\n    Set<File> sources =\n        new ImmutableSet.Builder<File>()\n            .addAll(filesUnderDirectory(javaDir, JAVA_FILE))\n            .addAll(filesUnderDirectory(javatestsDir, JAVA_FILE))\n            .build();\n    assertThat(sources).isNotEmpty();\n    JavaCompiler compiler = new EclipseCompiler();\n    StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);\n    // This hack is only needed in a Google-internal Java 8 environment where symbolic links make it\n    // hard for ecj to find the boot class path. Elsewhere it is unnecessary but harmless. Notably,\n    // on Java 9+ there is no rt.jar. There, fileManager.getLocation(PLATFORM_CLASS_PATH) returns\n    // null, because the relevant classes are in modules inside\n    // fileManager.getLocation(SYSTEM_MODULES).\n    File rtJar = new File(JAVA_HOME.value() + \"/lib/rt.jar\");\n    if (rtJar.exists()) {\n      List<File> bootClassPath =\n          ImmutableList.<File>builder()\n              .add(rtJar)\n              .addAll(fileManager.getLocation(StandardLocation.PLATFORM_CLASS_PATH))\n              .build();\n      fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, bootClassPath);\n    }\n    Iterable<? extends JavaFileObject> sourceFileObjects =\n        fileManager.getJavaFileObjectsFromFiles(sources);\n    String outputDir = tmp.getRoot().toString();\n    ImmutableList<String> options =\n        ImmutableList.of(\n            \"-d\",\n            outputDir,\n            \"-s\",\n            outputDir,\n            \"-source\",\n            version,\n            \"-target\",\n            version,\n            \"-warn:-warningToken,-intfAnnotation\");\n    JavaCompiler.CompilationTask task =\n        compiler.getTask(null, fileManager, null, options, null, sourceFileObjects);\n    // Explicitly supply an empty list of extensions for AutoValueProcessor, because otherwise this\n    // test will pick up a test one and get confused.\n    AutoValueProcessor autoValueProcessor = new AutoValueProcessor(ImmutableList.of());\n    ImmutableList<? extends Processor> processors =\n        ImmutableList.of(\n            autoValueProcessor,\n            new AutoOneOfProcessor(),\n            new AutoAnnotationProcessor(),\n            new AutoBuilderProcessor());\n    task.setProcessors(processors);\n    assertWithMessage(\"Compilation should succeed\").that(task.call()).isTrue();\n  }\n\n  private static ImmutableSet<File> filesUnderDirectory(File dir, Predicate<File> predicate)\n      throws IOException {\n    assertWithMessage(dir.toString()).that(dir.isDirectory()).isTrue();\n    try (Stream<Path> paths = Files.walk(dir.toPath())) {\n      return paths.map(Path::toFile).filter(predicate).collect(toImmutableSet());\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/GradleIT.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static java.nio.charset.StandardCharsets.UTF_8;\n\nimport com.google.common.collect.ImmutableList;\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.Optional;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport java.util.stream.Stream;\nimport org.gradle.testkit.runner.BuildResult;\nimport org.gradle.testkit.runner.GradleRunner;\nimport org.gradle.util.GradleVersion;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.rules.TemporaryFolder;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic class GradleIT {\n  @Rule public TemporaryFolder fakeProject = new TemporaryFolder();\n\n  private static final String BUILD_GRADLE_TEXT =\n      String.join(\n          \"\\n\",\n          \"plugins {\",\n          \"  id 'java-library'\",\n          \"}\",\n          \"repositories {\",\n          \"  maven { url = uri('${localRepository}') }\",\n          \"}\",\n          \"dependencies {\",\n          \"  compileOnlyApi     \"\n              + \" 'com.google.auto.value:auto-value-annotations:${autoValueVersion}'\",\n          \"  annotationProcessor 'com.google.auto.value:auto-value:${autoValueVersion}'\",\n          \"}\");\n\n  private static final String FOO_TEXT =\n      String.join(\n          \"\\n\",\n          \"package com.example;\",\n          \"\",\n          \"import com.google.auto.value.AutoValue;\",\n          \"\",\n          \"@AutoValue\",\n          \"abstract class Foo {\",\n          \"  abstract String bar();\",\n          \"\",\n          \"  static Foo of(String bar) {\",\n          \"    return new AutoValue_Foo(bar);\",\n          \"  }\",\n          \"}\");\n\n  private static final Optional<File> GRADLE_INSTALLATION = getGradleInstallation();\n\n  @Test\n  public void basic() throws IOException {\n    String autoValueVersion = System.getProperty(\"autoValueVersion\");\n    assertThat(autoValueVersion).isNotNull();\n    String localRepository = System.getProperty(\"localRepository\");\n    assertThat(localRepository).isNotNull();\n\n    // Set up the fake Gradle project.\n    String buildGradleText = expandSystemProperties(BUILD_GRADLE_TEXT);\n    writeFile(fakeProject.newFile(\"build.gradle\").toPath(), buildGradleText);\n    Path srcDir = fakeProject.newFolder(\"src\", \"main\", \"java\", \"com\", \"example\").toPath();\n    writeFile(srcDir.resolve(\"Foo.java\"), FOO_TEXT);\n\n    // Build it the first time.\n    BuildResult result1 = buildFakeProject();\n    assertThat(result1.getOutput())\n        .contains(\n            \"Full recompilation is required because no incremental change information is\"\n                + \" available\");\n    Path output =\n        fakeProject\n            .getRoot()\n            .toPath()\n            .resolve(\"build/classes/java/main/com/example/AutoValue_Foo.class\");\n    assertThat(Files.exists(output)).isTrue();\n\n    // Add a source file to the project.\n    String barText = FOO_TEXT.replace(\"Foo\", \"Bar\");\n    Path barFile = srcDir.resolve(\"Bar.java\");\n    writeFile(barFile, barText);\n\n    // Build it a second time.\n    BuildResult result2 = buildFakeProject();\n    assertThat(result2.getOutput()).doesNotContain(\"Full recompilation is required\");\n\n    // Remove the second source file and build a third time. If incremental annotation processing\n    // is not working, this will produce a message like this:\n    //   Full recompilation is required because com.google.auto.value.processor.AutoValueProcessor\n    //   is not incremental\n    Files.delete(barFile);\n    BuildResult result3 = buildFakeProject();\n    assertThat(result3.getOutput()).doesNotContain(\"Full recompilation is required\");\n  }\n\n  private BuildResult buildFakeProject() throws IOException {\n    GradleRunner runner =\n        GradleRunner.create()\n            .withProjectDir(fakeProject.getRoot())\n            .withArguments(\"--info\", \"compileJava\");\n    if (GRADLE_INSTALLATION.isPresent()) {\n      runner.withGradleInstallation(GRADLE_INSTALLATION.get());\n    } else {\n      runner.withGradleVersion(GradleVersion.current().getVersion());\n    }\n    return runner.build();\n  }\n\n  private static Optional<File> getGradleInstallation() {\n    String gradleHome = System.getenv(\"GRADLE_HOME\");\n    if (gradleHome != null) {\n      File gradleHomeFile = new File(gradleHome);\n      if (gradleHomeFile.isDirectory()) {\n        return Optional.of(new File(gradleHome));\n      }\n    }\n    try {\n      Path gradleExecutable = Paths.get(\"/usr/bin/gradle\");\n      Path gradleLink = gradleExecutable.resolveSibling(Files.readSymbolicLink(gradleExecutable));\n      if (!gradleLink.endsWith(\"bin/gradle\")) {\n        return Optional.empty();\n      }\n      Path installationPath = gradleLink.getParent().getParent();\n      if (!Files.isDirectory(installationPath)) {\n        return Optional.empty();\n      }\n      Optional<Path> coreJar;\n      Pattern corePattern = Pattern.compile(\"gradle-core-([0-9]+)\\\\..*\\\\.jar\");\n      try (Stream<Path> files = Files.walk(installationPath.resolve(\"lib\"))) {\n        coreJar =\n            files\n                .filter(\n                    p -> {\n                      Matcher matcher = corePattern.matcher(p.getFileName().toString());\n                      if (matcher.matches()) {\n                        int version = Integer.parseInt(matcher.group(1));\n                        if (version >= 5) {\n                          return true;\n                        }\n                      }\n                      return false;\n                    })\n                .findFirst();\n      }\n      return coreJar.map(unused -> installationPath.toFile());\n    } catch (IOException e) {\n      return Optional.empty();\n    }\n  }\n\n  private static String expandSystemProperties(String s) {\n    for (String name : System.getProperties().stringPropertyNames()) {\n      String value = System.getProperty(name);\n      s = s.replace(\"${\" + name + \"}\", value);\n    }\n    return s;\n  }\n\n  private static void writeFile(Path file, String text) throws IOException {\n    Files.write(file, ImmutableList.of(text), UTF_8);\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/KotlinData.kt",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value\n\nimport com.google.common.collect.ImmutableList\n\ndata class KotlinData(val int: Int, val string: String)\n\ndata class KotlinDataWithNullable(val anInt: Int?, val aString: String?)\n\ndata class KotlinDataWithDefaults(\n  val anInt: Int = 23,\n  val anImmutableList: ImmutableList<String> = ImmutableList.of(\"foo\"),\n  val notDefaulted: Long,\n  val aString: String = \"skidoo\",\n)\n\n// Exactly 8 defaulted properties, in case we have a problem with sign-extending byte bitmasks.\ndata class KotlinDataEightDefaults(\n  val a1: Int = 1,\n  val a2: Int = 2,\n  val a3: Int = 3,\n  val a4: Int = 4,\n  val a5: Int = 5,\n  val a6: Int = 6,\n  val a7: Int = 7,\n  val a8: Int = 8,\n)\n\ndata class KotlinDataSomeDefaults(\n  val requiredInt: Int,\n  val requiredString: String,\n  val optionalInt: Int = 23,\n  val optionalString: String = \"Skidoo\",\n)\n\n/**\n * Class with 2 required properties and 31 optional ones. This validates that we use the total count\n * of properties to compute how many default-value bitmasks the Kotlin constructor has. Using just\n * the number of optional properties would be wrong, and would show up as passing only one `int`\n * bitmask instead of two.\n */\ndata class KotlinDataSomeDefaultsBig(\n  val requiredInt: Int,\n  val requiredString: String,\n  val a1: Int = 1,\n  val a2: Int = 2,\n  val a3: Int = 3,\n  val a4: Int = 4,\n  val a5: Int = 5,\n  val a6: Int = 6,\n  val a7: Int = 7,\n  val a8: Int = 8,\n  val a9: Int = 9,\n  val a10: Int = 10,\n  val a11: Int = 11,\n  val a12: Int = 12,\n  val a13: Int = 13,\n  val a14: Int = 14,\n  val a15: Int = 15,\n  val a16: Int = 16,\n  val a17: Int = 17,\n  val a18: Int = 18,\n  val a19: Int = 19,\n  val a20: Int = 20,\n  val a21: Int = 21,\n  val a22: Int = 22,\n  val a23: Int = 23,\n  val a24: Int = 24,\n  val a25: Int = 25,\n  val a26: Int = 26,\n  val a27: Int = 27,\n  val a28: Int = 28,\n  val a29: Int = 29,\n  val a30: Int = 30,\n  val a31: Int = 31,\n)\n\n// CharSequence is an interface so the parameter appears from Java as List<? extends CharSequence>,\n// but getList() appears as returning List<CharSequence>.\ndata class KotlinDataWithList(val list: List<CharSequence>, val number: Int)\n\ndata class KotlinDataWithTypeParameters<\n  T,\n  U : Number,\n  out V : Number,\n  in W : Number,\n  out M : Map<String, *>,\n>(val t: T? = null, val u: U, val v: V, val m: M) {\n  fun foo(w: W) {}\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/SimpleValueTypeTest.java",
    "content": "/*\n * Copyright 2012 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertSame;\n\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.testing.NullPointerTester;\nimport java.util.Map;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class SimpleValueTypeTest {\n  @Test\n  public void testSimpleValueType() {\n    final String happy = \"happy\";\n    final int testInt = 23;\n    final Map<String, Long> testMap = ImmutableMap.of(\"happy\", 23L);\n    SimpleValueType simple = SimpleValueType.create(happy, testInt, testMap);\n    assertSame(happy, simple.string());\n    assertEquals(testInt, simple.integer());\n    assertSame(testMap, simple.map());\n    assertEquals(\"SimpleValueType{string=happy, integer=23, map={happy=23}}\", simple.toString());\n    int expectedHashCode = 1;\n    expectedHashCode = (expectedHashCode * 1000003) ^ happy.hashCode();\n    expectedHashCode = (expectedHashCode * 1000003) ^ ((Object) testInt).hashCode();\n    expectedHashCode = (expectedHashCode * 1000003) ^ testMap.hashCode();\n    assertEquals(expectedHashCode, simple.hashCode());\n  }\n\n  @Test\n  public void testNestedValueType() {\n    ImmutableMap<Integer, String> numberNames = ImmutableMap.of(1, \"un\", 2, \"deux\");\n    NestedValueType.Nested nested = NestedValueType.Nested.create(numberNames);\n    assertEquals(numberNames, nested.numberNames());\n  }\n\n  @Test\n  public void testNull() {\n    NullPointerTester tester = new NullPointerTester();\n    tester.testAllPublicStaticMethods(SimpleValueType.class);\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/annotations/Empty.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.annotations;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\n\n/**\n * An annotation with no members, for tests, and runtime retention so it can be accessed through\n * reflection.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface Empty {}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/annotations/GwtArrays.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.annotations;\n\nimport com.google.common.annotations.GwtCompatible;\n\n/**\n * An annotation that is marked {@code @GwtCompatible} and that contains an array member.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@GwtCompatible\npublic @interface GwtArrays {\n  String[] strings();\n\n  int[] ints();\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/annotations/StringValues.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.annotations;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\n\n/**\n * An annotation with one member, an array of strings with the default name {@code value}, and\n * runtime retention so it can be accessed through reflection.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface StringValues {\n  String[] value();\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/annotations/TestAnnotation.java",
    "content": "/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.annotations;\n\n/** Test annotation for AutoAnnotation and Kotlin. */\npublic @interface TestAnnotation {\n  String value() default \"default\";\n\n  int integer() default 23;\n\n  String[] values() default {};\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/enums/MyEnum.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.enums;\n\n/**\n * @author emcmanus@google.com (Éamonn McManus)\n */\npublic enum MyEnum {\n  ONE,\n  TWO,\n  BUCKLE_MY_SHOE\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/gwt/CustomFieldSerializerTest.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.gwt;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.common.truth.Truth.assertWithMessage;\n\nimport com.google.auto.value.AutoValue;\nimport com.google.common.annotations.GwtCompatible;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.reflect.Reflection;\nimport com.google.gwt.user.client.rpc.SerializationException;\nimport com.google.gwt.user.client.rpc.SerializationStreamWriter;\nimport java.io.Serializable;\nimport java.lang.reflect.Method;\nimport java.util.ArrayDeque;\nimport java.util.Collections;\nimport java.util.Deque;\nimport java.util.List;\nimport java.util.Map;\nimport javax.annotation.Nullable;\nimport org.junit.Test;\nimport org.junit.function.ThrowingRunnable;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * Tests that the generated GWT serializer for GwtValueType serializes fields in the expected way.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class CustomFieldSerializerTest {\n  @AutoValue\n  @GwtCompatible(serializable = true)\n  abstract static class ValueType implements Serializable {\n    abstract String string();\n\n    abstract int integer();\n\n    @Nullable\n    abstract ValueType other();\n\n    abstract List<ValueType> others();\n\n    static ValueType create(String string, int integer, @Nullable ValueType other) {\n      return create(string, integer, other, Collections.<ValueType>emptyList());\n    }\n\n    static ValueType create(\n        String string, int integer, @Nullable ValueType other, List<ValueType> others) {\n      return new AutoValue_CustomFieldSerializerTest_ValueType(string, integer, other, others);\n    }\n  }\n\n  private static final ValueType SIMPLE = ValueType.create(\"anotherstring\", 1729, null);\n  private static final ValueType CONS = ValueType.create(\"whatever\", 1296, SIMPLE);\n  private static final ValueType WITH_LIST =\n      ValueType.create(\"blim\", 11881376, SIMPLE, ImmutableList.of(SIMPLE, CONS));\n\n  private final MickeyMouseMock<SerializationStreamWriter> mock =\n      new MickeyMouseMock<>(SerializationStreamWriter.class);\n  private final SerializationStreamWriter streamWriter = mock.proxy();\n\n  @Test\n  public void testCustomFieldSerializer() throws SerializationException {\n    AutoValue_CustomFieldSerializerTest_ValueType withList =\n        (AutoValue_CustomFieldSerializerTest_ValueType) WITH_LIST;\n    AutoValue_CustomFieldSerializerTest_ValueType_CustomFieldSerializer.serialize(\n        streamWriter, withList);\n    mock.verify(\n        () -> {\n          streamWriter.writeString(\"blim\");\n          streamWriter.writeInt(11881376);\n          streamWriter.writeObject(SIMPLE);\n          streamWriter.writeObject(ImmutableList.of(SIMPLE, CONS));\n        });\n  }\n\n  @AutoValue\n  @GwtCompatible(serializable = true)\n  abstract static class ValueTypeWithGetters implements Serializable {\n    abstract String getPackage();\n\n    abstract boolean isDefault();\n\n    static ValueTypeWithGetters create(String pkg, boolean dflt) {\n      return new AutoValue_CustomFieldSerializerTest_ValueTypeWithGetters(pkg, dflt);\n    }\n  }\n\n  @Test\n  public void testCustomFieldSerializerWithGetters() throws SerializationException {\n    AutoValue_CustomFieldSerializerTest_ValueTypeWithGetters instance =\n        (AutoValue_CustomFieldSerializerTest_ValueTypeWithGetters)\n            ValueTypeWithGetters.create(\"package\", true);\n    AutoValue_CustomFieldSerializerTest_ValueTypeWithGetters_CustomFieldSerializer.serialize(\n        streamWriter, instance);\n    mock.verify(\n        () -> {\n          streamWriter.writeString(\"package\");\n          streamWriter.writeBoolean(true);\n        });\n  }\n\n  @AutoValue\n  @GwtCompatible(serializable = true)\n  abstract static class GenericValueType<K extends Comparable<K>, V extends K>\n      implements Serializable {\n    abstract Map<K, V> map();\n\n    static <K extends Comparable<K>, V extends K> GenericValueType<K, V> create(Map<K, V> map) {\n      return new AutoValue_CustomFieldSerializerTest_GenericValueType<K, V>(map);\n    }\n  }\n\n  @Test\n  public void testCustomFieldSerializerGeneric() throws SerializationException {\n    Map<Integer, Integer> map = ImmutableMap.of(2, 2);\n    AutoValue_CustomFieldSerializerTest_GenericValueType<Integer, Integer> instance =\n        (AutoValue_CustomFieldSerializerTest_GenericValueType<Integer, Integer>)\n            GenericValueType.create(map);\n    AutoValue_CustomFieldSerializerTest_GenericValueType_CustomFieldSerializer.serialize(\n        streamWriter, instance);\n    mock.verify(\n        () -> {\n          streamWriter.writeObject(map);\n        });\n  }\n\n  @AutoValue\n  @GwtCompatible(serializable = true)\n  abstract static class ValueTypeWithBuilder implements Serializable {\n    abstract String string();\n\n    abstract ImmutableList<String> strings();\n\n    static Builder builder() {\n      return new AutoValue_CustomFieldSerializerTest_ValueTypeWithBuilder.Builder();\n    }\n\n    @AutoValue.Builder\n    interface Builder {\n      Builder string(String x);\n\n      Builder strings(ImmutableList<String> x);\n\n      ValueTypeWithBuilder build();\n    }\n  }\n\n  @Test\n  public void testCustomFieldSerializerWithBuilder() throws SerializationException {\n    AutoValue_CustomFieldSerializerTest_ValueTypeWithBuilder instance =\n        (AutoValue_CustomFieldSerializerTest_ValueTypeWithBuilder)\n            ValueTypeWithBuilder.builder().string(\"s\").strings(ImmutableList.of(\"a\", \"b\")).build();\n    AutoValue_CustomFieldSerializerTest_ValueTypeWithBuilder_CustomFieldSerializer.serialize(\n        streamWriter, instance);\n    mock.verify(\n        () -> {\n          streamWriter.writeString(\"s\");\n          streamWriter.writeObject(ImmutableList.of(\"a\", \"b\"));\n        });\n  }\n\n  @AutoValue\n  @GwtCompatible(serializable = true)\n  abstract static class ValueTypeWithBuilderAndGetters implements Serializable {\n    abstract String getPackage();\n\n    abstract boolean isDefault();\n\n    static Builder builder() {\n      return new AutoValue_CustomFieldSerializerTest_ValueTypeWithBuilderAndGetters.Builder();\n    }\n\n    @AutoValue.Builder\n    interface Builder {\n      Builder setPackage(String x);\n\n      Builder setDefault(boolean x);\n\n      ValueTypeWithBuilderAndGetters build();\n    }\n  }\n\n  @Test\n  public void testCustomFieldSerializerWithBuilderAndGetters() throws SerializationException {\n    AutoValue_CustomFieldSerializerTest_ValueTypeWithBuilderAndGetters instance =\n        (AutoValue_CustomFieldSerializerTest_ValueTypeWithBuilderAndGetters)\n            ValueTypeWithBuilderAndGetters.builder().setPackage(\"s\").setDefault(false).build();\n    AutoValue_CustomFieldSerializerTest_ValueTypeWithBuilderAndGetters_CustomFieldSerializer\n        .serialize(streamWriter, instance);\n    mock.verify(\n        () -> {\n          streamWriter.writeString(\"s\");\n          streamWriter.writeBoolean(false);\n        });\n  }\n\n  @AutoValue\n  @GwtCompatible(serializable = true)\n  abstract static class GenericValueTypeWithBuilder<K extends Comparable<K>, V extends K>\n      implements Serializable {\n    abstract Map<K, V> map();\n\n    static <K extends Comparable<K>, V extends K> Builder<K, V> builder() {\n      return new AutoValue_CustomFieldSerializerTest_GenericValueTypeWithBuilder.Builder<K, V>();\n    }\n\n    @AutoValue.Builder\n    interface Builder<K extends Comparable<K>, V extends K> {\n      Builder<K, V> map(Map<K, V> map);\n\n      GenericValueTypeWithBuilder<K, V> build();\n    }\n  }\n\n  @Test\n  public void testCustomFieldSerializerGenericWithBuilder() throws SerializationException {\n    Map<Integer, Integer> map = ImmutableMap.of(2, 2);\n    AutoValue_CustomFieldSerializerTest_GenericValueTypeWithBuilder<Integer, Integer> instance =\n        (AutoValue_CustomFieldSerializerTest_GenericValueTypeWithBuilder<Integer, Integer>)\n            GenericValueTypeWithBuilder.<Integer, Integer>builder().map(map).build();\n    AutoValue_CustomFieldSerializerTest_GenericValueTypeWithBuilder_CustomFieldSerializer.serialize(\n        streamWriter, instance);\n    mock.verify(\n        () -> {\n          streamWriter.writeObject(map);\n        });\n  }\n\n  @AutoValue\n  abstract static class MethodCall {\n    abstract String method();\n\n    abstract ImmutableList<Object> args();\n\n    static MethodCall of(String method, ImmutableList<Object> args) {\n      return new AutoValue_CustomFieldSerializerTest_MethodCall(method, args);\n    }\n  }\n\n  /**\n   * A trivial home-made mocking framework.\n   *\n   * <p>Mockito 5 no longer supports Java 8, and we do, so rather than pinning to an older version\n   * of Mockito we fake it with {@link Reflection}. This is only really possible because the thing\n   * we want to mock ({@link SerializationStreamWriter}) is an interface. Furthermore all its\n   * methods return void so we don't even need a way to specify what to return.\n   *\n   * <p>The idea is that you make an instance of this class, have the code under test call methods\n   * on it, then call {@link #verify} with a lambda that repeats the expected calls. If they match\n   * the actual calls then the test passes.\n   */\n  private static class MickeyMouseMock<T> {\n    private boolean recording = true;\n    private final Deque<MethodCall> methodCalls = new ArrayDeque<>();\n    private final T proxy;\n\n    MickeyMouseMock(Class<T> intf) {\n      this.proxy = Reflection.newProxy(intf, this::invocationHandler);\n    }\n\n    T proxy() {\n      return proxy;\n    }\n\n    void verify(ThrowingRunnable actions) {\n      assertThat(recording).isTrue();\n      recording = false;\n      try {\n        actions.run();\n      } catch (AssertionError e) {\n        throw e;\n      } catch (Throwable t) {\n        throw new AssertionError(t);\n      }\n      assertThat(methodCalls).isEmpty();\n    }\n\n    private Object invocationHandler(Object proxy, Method method, Object[] args) {\n      if (args == null) {\n        args = new Object[0];\n      }\n      MethodCall methodCall = MethodCall.of(method.getName(), ImmutableList.copyOf(args));\n      if (recording) {\n        methodCalls.add(methodCall);\n      } else { // verifying\n        assertWithMessage(\"Missing call %s\", methodCall).that(methodCalls).isNotEmpty();\n        MethodCall recorded = methodCalls.removeFirst();\n        assertThat(methodCall).isEqualTo(recorded);\n      }\n      return null;\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/gwt/EmptyExtension.java",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.gwt;\n\nimport static java.util.stream.Collectors.joining;\n\nimport com.google.auto.service.AutoService;\nimport com.google.auto.value.extension.AutoValueExtension;\nimport com.google.common.base.Joiner;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.escapevelocity.Template;\nimport java.io.IOException;\nimport java.io.StringReader;\nimport java.util.List;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.TypeParameterElement;\nimport javax.lang.model.type.TypeMirror;\n\n/** An AutoValue extension that generates a subclass that does nothing useful. */\n@AutoService(AutoValueExtension.class)\npublic class EmptyExtension extends AutoValueExtension {\n  // TODO(emcmanus): it is way too difficult to write a trivial extension. Problems we have here:\n  //   (1) We have to generate a constructor that calls the superclass constructor, which means\n  //       declaring the appropriate constructor parameters and then forwarding them to a super\n  //       call.\n  //   (2) We have to avoid generating variable names that are keywords (we append $ here\n  //       to avoid that).\n  //   (3) We have to concoct appropriate type parameter strings, for example\n  //       final class AutoValue_Foo<K extends Comparable<K>, V> extends $AutoValue_Foo<K, V>.\n  //   These problems show up with the template approach here, but also using JavaPoet as the\n  //   Memoize extension does.\n  private static final ImmutableList<String> TEMPLATE_LINES =\n      ImmutableList.of(\n          \"package $package;\",\n          \"\\n\",\n          \"#if ($isFinal) final #end class ${className}${formalTypes}\"\n              + \" extends ${classToExtend}${actualTypes} {\\n\",\n          \"  ${className}(\",\n          \"    #foreach ($property in $propertyTypes.keySet())\",\n          \"    $propertyTypes[$property] ${property}$ #if ($foreach.hasNext) , #end\",\n          \"    #end\",\n          \"  ) {\",\n          \"    super(\",\n          \"      #foreach ($property in $propertyTypes.keySet())\",\n          \"      ${property}$ #if ($foreach.hasNext) , #end\",\n          \"      #end\",\n          \"    );\",\n          \"  }\",\n          \"}\");\n\n  @Override\n  public boolean applicable(Context context) {\n    return true;\n  }\n\n  @Override\n  public String generateClass(\n      Context context, String className, String classToExtend, boolean isFinal) {\n    String templateString = Joiner.on('\\n').join(TEMPLATE_LINES);\n    StringReader templateReader = new StringReader(templateString);\n    Template template;\n    try {\n      template = Template.parseFrom(templateReader);\n    } catch (IOException e) {\n      throw new RuntimeException(e);\n    }\n    TypeElement autoValueClass = context.autoValueClass();\n    ImmutableMap<String, Object> vars =\n        ImmutableMap.<String, Object>builder()\n            .put(\"package\", context.packageName())\n            .put(\"className\", className)\n            .put(\"classToExtend\", classToExtend)\n            .put(\"isFinal\", isFinal)\n            .put(\"propertyTypes\", context.propertyTypes())\n            .put(\"formalTypes\", formalTypeParametersString(autoValueClass))\n            .put(\"actualTypes\", actualTypeParametersString(autoValueClass))\n            .build();\n    return template.evaluate(vars);\n  }\n\n  private static String actualTypeParametersString(TypeElement type) {\n    List<? extends TypeParameterElement> typeParameters = type.getTypeParameters();\n    if (typeParameters.isEmpty()) {\n      return \"\";\n    }\n    return typeParameters.stream()\n        .map(e -> e.getSimpleName().toString())\n        .collect(joining(\", \", \"<\", \">\"));\n  }\n\n  private static String formalTypeParametersString(TypeElement type) {\n    List<? extends TypeParameterElement> typeParameters = type.getTypeParameters();\n    if (typeParameters.isEmpty()) {\n      return \"\";\n    }\n    StringBuilder sb = new StringBuilder(\"<\");\n    String sep = \"\";\n    for (TypeParameterElement typeParameter : typeParameters) {\n      sb.append(sep);\n      sep = \", \";\n      appendTypeParameterWithBounds(typeParameter, sb);\n    }\n    return sb.append(\">\").toString();\n  }\n\n  private static void appendTypeParameterWithBounds(\n      TypeParameterElement typeParameter, StringBuilder sb) {\n    sb.append(typeParameter.getSimpleName());\n    String sep = \" extends \";\n    for (TypeMirror bound : typeParameter.getBounds()) {\n      if (!bound.toString().equals(\"java.lang.Object\")) {\n        sb.append(sep);\n        sep = \" & \";\n        sb.append(bound);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/gwt/GwtCompilationTest.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.gwt;\n\nimport static com.google.testing.compile.CompilationSubject.assertThat;\nimport static com.google.testing.compile.Compiler.javac;\n\nimport com.google.auto.value.processor.AutoValueProcessor;\nimport com.google.testing.compile.Compilation;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.lang.model.SourceVersion;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * Test of generated source for GWT serialization classes.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class GwtCompilationTest {\n  private static final JavaFileObject GWT_COMPATIBLE =\n      JavaFileObjects.forSourceLines(\n          \"com.google.annotations.GwtCompatible\",\n          \"package com.google.annotations;\",\n          \"\",\n          \"public @interface GwtCompatible {\",\n          \"  boolean serializable() default false;\",\n          \"}\");\n\n  /**\n   * Test where the serialized properties don't include generics, so no {@code @SuppressWarnings}\n   * annotation is needed. We explicitly check that one is not included anyway, because Eclipse for\n   * example can be configured to complain about unnecessary warning suppression.\n   */\n  @Test\n  public void testBasic() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.annotations.GwtCompatible;\",\n            \"\",\n            \"@AutoValue\",\n            \"@GwtCompatible(serializable = true)\",\n            \"public abstract class Baz {\",\n            \"  public abstract int buh();\",\n            \"\",\n            \"  public static Baz create(int buh) {\",\n            \"    return new AutoValue_Baz(buh);\",\n            \"  }\",\n            \"}\");\n    JavaFileObject expectedOutput =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.AutoValue_Baz_CustomFieldSerializer\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.gwt.user.client.rpc.CustomFieldSerializer;\",\n            \"import com.google.gwt.user.client.rpc.SerializationException;\",\n            \"import com.google.gwt.user.client.rpc.SerializationStreamReader;\",\n            \"import com.google.gwt.user.client.rpc.SerializationStreamWriter;\",\n            \"import \" + generatedAnnotationType() + \";\",\n            \"\",\n            \"@Generated(\\\"com.google.auto.value.processor.AutoValueProcessor\\\")\",\n            \"public final class AutoValue_Baz_CustomFieldSerializer\"\n                + \" extends CustomFieldSerializer<AutoValue_Baz> {\",\n            \"\",\n            \"  public static AutoValue_Baz instantiate(\",\n            \"      SerializationStreamReader streamReader) throws SerializationException {\",\n            \"    int buh = streamReader.readInt();\",\n            \"    return new AutoValue_Baz(buh);\",\n            \"  }\",\n            \"\",\n            \"  public static void serialize(\",\n            \"      SerializationStreamWriter streamWriter,\",\n            \"      AutoValue_Baz instance) throws SerializationException {\",\n            \"    streamWriter.writeInt(instance.buh());\",\n            \"  }\",\n            \"\",\n            \"  public static void deserialize(\",\n            \"      @SuppressWarnings(\\\"unused\\\") SerializationStreamReader streamReader,\",\n            \"      @SuppressWarnings(\\\"unused\\\") AutoValue_Baz instance) {\",\n            \"  }\",\n            \"\",\n            \"  @SuppressWarnings(\\\"unused\\\") private int dummy_3f8e1b04;\",\n            \"\",\n            \"  @Override\",\n            \"  public void deserializeInstance(\",\n            \"      SerializationStreamReader streamReader,\",\n            \"      AutoValue_Baz instance) {\",\n            \"    deserialize(streamReader, instance);\",\n            \"  }\",\n            \"\",\n            \"  @Override\",\n            \"  public boolean hasCustomInstantiateInstance() {\",\n            \"    return true;\",\n            \"  }\",\n            \"\",\n            \"  @Override\",\n            \"  public AutoValue_Baz instantiateInstance(\",\n            \"      SerializationStreamReader streamReader) throws SerializationException {\",\n            \"    return instantiate(streamReader);\",\n            \"  }\",\n            \"\",\n            \"  @Override\",\n            \"  public void serializeInstance(\",\n            \"    SerializationStreamWriter streamWriter,\",\n            \"    AutoValue_Baz instance) throws SerializationException {\",\n            \"    serialize(streamWriter, instance);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject, GWT_COMPATIBLE);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Baz_CustomFieldSerializer\")\n        .hasSourceEquivalentTo(expectedOutput);\n  }\n\n  /**\n   * Test where the serialized properties don't include generics, so a {@code @SuppressWarnings}\n   * annotation is needed.\n   */\n  @Test\n  public void testSuppressWarnings() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.annotations.GwtCompatible;\",\n            \"\",\n            \"import java.util.List;\",\n            \"\",\n            \"@AutoValue\",\n            \"@GwtCompatible(serializable = true)\",\n            \"public abstract class Baz {\",\n            \"  public abstract List<String> buh();\",\n            \"\",\n            \"  public static Baz create(List<String> buh) {\",\n            \"    return new AutoValue_Baz(buh);\",\n            \"  }\",\n            \"}\");\n    JavaFileObject expectedOutput =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.AutoValue_Baz_CustomFieldSerializer\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.gwt.user.client.rpc.CustomFieldSerializer;\",\n            \"import com.google.gwt.user.client.rpc.SerializationException;\",\n            \"import com.google.gwt.user.client.rpc.SerializationStreamReader;\",\n            \"import com.google.gwt.user.client.rpc.SerializationStreamWriter;\",\n            \"import java.util.List;\",\n            \"import \" + generatedAnnotationType() + \";\",\n            \"\",\n            \"@Generated(\\\"com.google.auto.value.processor.AutoValueProcessor\\\")\",\n            \"public final class AutoValue_Baz_CustomFieldSerializer\"\n                + \" extends CustomFieldSerializer<AutoValue_Baz> {\",\n            \"\",\n            \"  public static AutoValue_Baz instantiate(\",\n            \"      SerializationStreamReader streamReader) throws SerializationException {\",\n            \"    @SuppressWarnings(\\\"unchecked\\\")\",\n            \"    List<String> buh = (List<String>) streamReader.readObject();\",\n            \"    return new AutoValue_Baz(buh);\",\n            \"  }\",\n            \"\",\n            \"  public static void serialize(\",\n            \"      SerializationStreamWriter streamWriter,\",\n            \"      AutoValue_Baz instance) throws SerializationException {\",\n            \"    streamWriter.writeObject(instance.buh());\",\n            \"  }\",\n            \"\",\n            \"  public static void deserialize(\",\n            \"      @SuppressWarnings(\\\"unused\\\") SerializationStreamReader streamReader,\",\n            \"      @SuppressWarnings(\\\"unused\\\") AutoValue_Baz instance) {\",\n            \"  }\",\n            \"\",\n            \"  @SuppressWarnings(\\\"unused\\\") private int dummy_949e312e;\",\n            \"\",\n            \"  @Override\",\n            \"  public void deserializeInstance(\",\n            \"      SerializationStreamReader streamReader,\",\n            \"      AutoValue_Baz instance) {\",\n            \"    deserialize(streamReader, instance);\",\n            \"  }\",\n            \"\",\n            \"  @Override\",\n            \"  public boolean hasCustomInstantiateInstance() {\",\n            \"    return true;\",\n            \"  }\",\n            \"\",\n            \"  @Override\",\n            \"  public AutoValue_Baz instantiateInstance(\",\n            \"      SerializationStreamReader streamReader) throws SerializationException {\",\n            \"    return instantiate(streamReader);\",\n            \"  }\",\n            \"\",\n            \"  @Override\",\n            \"  public void serializeInstance(\",\n            \"    SerializationStreamWriter streamWriter,\",\n            \"    AutoValue_Baz instance) throws SerializationException {\",\n            \"    serialize(streamWriter, instance);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject, GWT_COMPATIBLE);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Baz_CustomFieldSerializer\")\n        .hasSourceEquivalentTo(expectedOutput);\n  }\n\n  /**\n   * Test builders and classes that are generic (as opposed to just containing properties with\n   * generics).\n   */\n  @Test\n  public void testBuildersAndGenerics() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.annotations.GwtCompatible;\",\n            \"import com.google.common.collect.ImmutableMap;\",\n            \"import java.util.Map;\",\n            \"\",\n            \"@AutoValue\",\n            \"@GwtCompatible(serializable = true)\",\n            \"public abstract class Baz<K extends Comparable<K>, V extends K> {\",\n            \"  public abstract Map<K, V> map();\",\n            \"  public abstract ImmutableMap<K, V> immutableMap();\",\n            \"\",\n            \"  public static <K extends Comparable<K>, V extends K> Builder<K, V> builder() {\",\n            \"    return new AutoValue_Baz.Builder<K, V>();\",\n            \"  }\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<K extends Comparable<K>, V extends K> {\",\n            \"    Builder<K, V> map(Map<K, V> map);\",\n            \"    ImmutableMap.Builder<K, V> immutableMapBuilder();\",\n            \"    Baz<K, V> build();\",\n            \"  }\",\n            \"}\");\n    JavaFileObject expectedOutput =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.AutoValue_Baz_CustomFieldSerializer\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.common.collect.ImmutableMap;\",\n            \"import com.google.gwt.user.client.rpc.CustomFieldSerializer;\",\n            \"import com.google.gwt.user.client.rpc.SerializationException;\",\n            \"import com.google.gwt.user.client.rpc.SerializationStreamReader;\",\n            \"import com.google.gwt.user.client.rpc.SerializationStreamWriter;\",\n            \"import java.util.Map;\",\n            \"import \" + generatedAnnotationType() + \";\",\n            \"\",\n            \"@Generated(\\\"com.google.auto.value.processor.AutoValueProcessor\\\")\",\n            \"public final class AutoValue_Baz_CustomFieldSerializer\"\n                + \"<K extends Comparable<K>, V extends K>\"\n                + \" extends CustomFieldSerializer<AutoValue_Baz<K, V>> {\",\n            \"\",\n            \"  public static <K extends Comparable<K>, V extends K> AutoValue_Baz<K, V>\"\n                + \" instantiate(\",\n            \"      SerializationStreamReader streamReader) throws SerializationException {\",\n            \"    @SuppressWarnings(\\\"unchecked\\\")\",\n            \"    Map<K, V> map = (Map<K, V>) streamReader.readObject();\",\n            \"    @SuppressWarnings(\\\"unchecked\\\")\",\n            \"    ImmutableMap<K, V> immutableMap = (ImmutableMap<K, V>) streamReader.readObject();\",\n            \"    AutoValue_Baz.Builder<K, V> builder$ = new AutoValue_Baz.Builder<K, V>();\",\n            \"    builder$.map(map);\",\n            \"    builder$.immutableMapBuilder().putAll(immutableMap);\",\n            \"    return (AutoValue_Baz<K, V>) builder$.build();\",\n            \"  }\",\n            \"\",\n            \"  public static <K extends Comparable<K>, V extends K> void serialize(\",\n            \"      SerializationStreamWriter streamWriter,\",\n            \"      AutoValue_Baz<K, V> instance) throws SerializationException {\",\n            \"    streamWriter.writeObject(instance.map());\",\n            \"    streamWriter.writeObject(instance.immutableMap());\",\n            \"  }\",\n            \"\",\n            \"  public static <K extends Comparable<K>, V extends K> void deserialize(\",\n            \"      @SuppressWarnings(\\\"unused\\\") SerializationStreamReader streamReader,\",\n            \"      @SuppressWarnings(\\\"unused\\\") AutoValue_Baz<K, V> instance) {\",\n            \"  }\",\n            \"\",\n            \"  @SuppressWarnings(\\\"unused\\\")\",\n            \"  private int dummy_2865d9ec;\",\n            \"\",\n            \"  @Override\",\n            \"  public void deserializeInstance(\",\n            \"      SerializationStreamReader streamReader,\",\n            \"      AutoValue_Baz<K, V> instance) {\",\n            \"    deserialize(streamReader, instance);\",\n            \"  }\",\n            \"\",\n            \"  @Override\",\n            \"  public boolean hasCustomInstantiateInstance() {\",\n            \"    return true;\",\n            \"  }\",\n            \"\",\n            \"  @Override\",\n            \"  public AutoValue_Baz<K, V> instantiateInstance(\",\n            \"      SerializationStreamReader streamReader) throws SerializationException {\",\n            \"    return instantiate(streamReader);\",\n            \"  }\",\n            \"\",\n            \"  @Override\",\n            \"  public void serializeInstance(\",\n            \"    SerializationStreamWriter streamWriter,\",\n            \"    AutoValue_Baz<K, V> instance) throws SerializationException {\",\n            \"    serialize(streamWriter, instance);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject, GWT_COMPATIBLE);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Baz_CustomFieldSerializer\")\n        .hasSourceEquivalentTo(expectedOutput);\n  }\n\n  private String generatedAnnotationType() {\n    return isJavaxAnnotationProcessingGeneratedAvailable()\n        ? \"javax.annotation.processing.Generated\"\n        : \"javax.annotation.Generated\";\n  }\n\n  private boolean isJavaxAnnotationProcessingGeneratedAvailable() {\n    return SourceVersion.latestSupported().compareTo(SourceVersion.RELEASE_8) > 0;\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/gwt/GwtValueType.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.gwt;\n\nimport com.google.auto.value.AutoValue;\nimport com.google.common.annotations.GwtCompatible;\nimport java.io.Serializable;\nimport java.util.Collections;\nimport java.util.List;\nimport javax.annotation.Nullable;\n\n/**\n * A class that is serializable with both Java and GWT serialization.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@AutoValue\n@GwtCompatible(serializable = true)\nabstract class GwtValueType implements Serializable {\n  abstract String string();\n\n  abstract int integer();\n\n  @Nullable\n  abstract GwtValueType other();\n\n  abstract List<GwtValueType> others();\n\n  static GwtValueType create(String string, int integer, @Nullable GwtValueType other) {\n    return create(string, integer, other, Collections.<GwtValueType>emptyList());\n  }\n\n  static GwtValueType create(\n      String string, int integer, @Nullable GwtValueType other, List<GwtValueType> others) {\n    return new AutoValue_GwtValueType(string, integer, other, others);\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/gwt/GwtValueTypeWithBuilder.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.gwt;\n\nimport com.google.auto.value.AutoValue;\nimport com.google.common.annotations.GwtCompatible;\nimport com.google.common.collect.ImmutableList;\nimport java.io.Serializable;\nimport java.util.List;\nimport javax.annotation.Nullable;\n\n/**\n * A class that is serializable with both Java and GWT serialization.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@AutoValue\n@GwtCompatible(serializable = true)\nabstract class GwtValueTypeWithBuilder<T> implements Serializable {\n  abstract String string();\n\n  abstract int integer();\n\n  @Nullable\n  abstract GwtValueTypeWithBuilder<T> other();\n\n  abstract List<GwtValueTypeWithBuilder<T>> others();\n\n  abstract ImmutableList<T> list();\n\n  abstract ImmutableList<T> otherList();\n\n  abstract ImmutableList<String> listWithBuilder();\n\n  static <T> Builder<T> builder() {\n    return new AutoValue_GwtValueTypeWithBuilder.Builder<T>();\n  }\n\n  @AutoValue.Builder\n  interface Builder<T> {\n    Builder<T> string(String x);\n\n    Builder<T> integer(int x);\n\n    Builder<T> other(@Nullable GwtValueTypeWithBuilder<T> x);\n\n    Builder<T> others(List<GwtValueTypeWithBuilder<T>> x);\n\n    Builder<T> list(ImmutableList<T> x);\n\n    Builder<T> otherList(List<T> x);\n\n    ImmutableList.Builder<String> listWithBuilderBuilder();\n\n    GwtValueTypeWithBuilder<T> build();\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/gwt/NonSerializableGwtValueType.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.gwt;\n\nimport com.google.auto.value.AutoValue;\nimport com.google.common.annotations.GwtCompatible;\nimport java.io.Serializable;\n\n/**\n * A class that is serializable with native Java serialization but not with GWT serialization.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@AutoValue\n@GwtCompatible\nabstract class NonSerializableGwtValueType implements Serializable {\n  abstract String string();\n\n  abstract int integer();\n\n  static NonSerializableGwtValueType create(String string, int integer) {\n    return new AutoValue_NonSerializableGwtValueType(string, integer);\n  }\n}\n"
  },
  {
    "path": "value/src/it/functional/src/test/java/com/google/auto/value/gwt/SerialSignatureTest.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.gwt;\n\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertNotNull;\nimport static org.junit.Assert.assertNull;\n\nimport com.google.auto.value.AutoValue;\nimport com.google.common.annotations.GwtCompatible;\nimport java.lang.reflect.Field;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * Tests that the generated serializer class for a GWT-serializable class contains a dummy field to\n * influence the signature, and that different classes have different signatures.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class SerialSignatureTest {\n  @AutoValue\n  @GwtCompatible(serializable = true)\n  abstract static class One {\n    abstract int foo();\n\n    static One create(int foo) {\n      return new AutoValue_SerialSignatureTest_One(foo);\n    }\n  }\n\n  @AutoValue\n  @GwtCompatible(serializable = true)\n  abstract static class Two {\n    abstract int foo();\n\n    static Two create(int foo) {\n      return new AutoValue_SerialSignatureTest_Two(foo);\n    }\n  }\n\n  @Test\n  public void testSerialSignatures() {\n    Class<?> serializerOne = AutoValue_SerialSignatureTest_One_CustomFieldSerializer.class;\n    Class<?> serializerTwo = AutoValue_SerialSignatureTest_Two_CustomFieldSerializer.class;\n    String fieldNameOne = dummySignatureFieldName(serializerOne);\n    String fieldNameTwo = dummySignatureFieldName(serializerTwo);\n    assertFalse(fieldNameOne.equals(fieldNameTwo));\n  }\n\n  private static String dummySignatureFieldName(Class<?> c) {\n    String name = null;\n    for (Field f : c.getDeclaredFields()) {\n      if (f.getName().startsWith(\"dummy_\")) {\n        assertNull(\"More than one field begins with dummy_: \" + name + \", \" + f.getName(), name);\n      }\n      name = f.getName();\n    }\n    assertNotNull(\"No field begins with dummy_\", name);\n    return name;\n  }\n}\n"
  },
  {
    "path": "value/src/it/gwtserializer/invoker.properties",
    "content": "invoker.goals = clean verify\n"
  },
  {
    "path": "value/src/it/gwtserializer/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Copyright 2015 Google LLC\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n-->\n<!-- TODO(gak): see if we can manage these dependencies any better -->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>com.google.auto.value</groupId>\n    <artifactId>auto-value-parent</artifactId>\n    <version>HEAD-SNAPSHOT</version>\n    <relativePath>../../../pom.xml</relativePath>\n  </parent>\n  <url>https://github.com/google/auto/tree/main/value</url>\n\n  <groupId>com.google.auto.value.it.gwtserializer</groupId>\n  <artifactId>gwtserializer</artifactId>\n  <version>HEAD-SNAPSHOT</version>\n  <name>Auto-Value GWT-RPC Serialization Integration Test</name>\n  <dependencyManagement>\n    <dependencies>\n      <dependency>\n        <groupId>org.gwtproject</groupId>\n        <artifactId>gwt</artifactId>\n        <version>2.13.0</version>\n        <type>pom</type>\n        <scope>import</scope>\n      </dependency>\n    </dependencies>\n  </dependencyManagement>\n  <dependencies>\n    <dependency>\n      <groupId>com.google.auto.value</groupId>\n      <artifactId>auto-value-annotations</artifactId>\n      <version>${project.version}</version>\n    </dependency>\n    <dependency>\n      <groupId>org.gwtproject</groupId>\n      <artifactId>gwt-user</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.gwtproject</groupId>\n      <artifactId>gwt-dev</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>guava</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>guava-gwt</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>junit</groupId>\n      <artifactId>junit</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <testResources>\n      <testResource>\n        <directory>src/test/java</directory>\n      </testResource>\n      <testResource>\n        <directory>${project.build.directory}/generated-test-sources/test-annotations</directory>\n      </testResource>\n    </testResources>\n    <plugins>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-compiler-plugin</artifactId>\n        <version>3.15.0</version>\n        <configuration>\n          <source>1.8</source>\n          <target>1.8</target>\n          <compilerArgument>-Xlint:all</compilerArgument>\n          <showWarnings>true</showWarnings>\n          <showDeprecation>true</showDeprecation>\n          <annotationProcessorPaths>\n            <path>\n              <groupId>com.google.auto.value</groupId>\n              <artifactId>auto-value</artifactId>\n              <version>${project.version}</version>\n            </path>\n          </annotationProcessorPaths>\n        </configuration>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-surefire-plugin</artifactId>\n        <configuration>\n          <skipTests>true</skipTests>\n        </configuration>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-resources-plugin</artifactId>\n        <version>3.5.0</version>\n        <executions>\n          <execution>\n            <!-- postpone resources:testResources until after compiler:testCompile to get generated sources -->\n            <id>default-testResources</id>\n            <phase>process-test-classes</phase>\n          </execution>\n        </executions>\n      </plugin>\n      <plugin>\n        <groupId>net.ltgt.gwt.maven</groupId>\n        <artifactId>gwt-maven-plugin</artifactId>\n        <version>1.2.0</version>\n        <executions>\n          <execution>\n            <goals>\n              <goal>test</goal>\n            </goals>\n          </execution>\n        </executions>\n      </plugin>\n      <plugin>\n        <groupId>org.sonatype.central</groupId>\n        <artifactId>central-publishing-maven-plugin</artifactId>\n        <configuration>\n          <skipPublishing>true</skipPublishing>\n        </configuration>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-gpg-plugin</artifactId>\n        <configuration>\n          <skip>true</skip>\n        </configuration>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-jar-plugin</artifactId>\n        <version>3.5.0</version>\n        <executions>\n          <execution>\n            <id>default-jar</id>\n            <phase>install</phase>\n          </execution>\n        </executions>\n      </plugin>\n    </plugins>\n  </build>\n</project>\n"
  },
  {
    "path": "value/src/it/gwtserializer/src/test/java/com/google/auto/value/GwtSerializerSuite.gwt.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Copyright 2015 Google LLC\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n-->\n<module>\n  <inherits name=\"com.google.gwt.user.User\" />\n\n  <servlet path=\"/test\" class=\"com.google.auto.value.client.GwtSerializerTest$TestServiceImpl\" />\n</module>\n"
  },
  {
    "path": "value/src/it/gwtserializer/src/test/java/com/google/auto/value/GwtSerializerSuite.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value;\n\nimport com.google.auto.value.client.GwtSerializerTest;\nimport com.google.gwt.junit.tools.GWTTestSuite;\nimport junit.framework.Test;\n\npublic class GwtSerializerSuite {\n  public static Test suite() {\n    GWTTestSuite suite = new GWTTestSuite();\n\n    suite.addTestSuite(GwtSerializerTest.class);\n\n    return suite;\n  }\n}\n"
  },
  {
    "path": "value/src/it/gwtserializer/src/test/java/com/google/auto/value/client/GwtSerializerTest.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.client;\n\nimport com.google.auto.value.AutoValue;\nimport com.google.common.annotations.GwtCompatible;\nimport com.google.common.annotations.GwtIncompatible;\nimport com.google.gwt.core.client.GWT;\nimport com.google.gwt.junit.client.GWTTestCase;\nimport com.google.gwt.user.client.rpc.AsyncCallback;\nimport com.google.gwt.user.client.rpc.RemoteService;\nimport com.google.gwt.user.client.rpc.RemoteServiceRelativePath;\nimport com.google.gwt.user.server.rpc.RemoteServiceServlet;\n\npublic class GwtSerializerTest extends GWTTestCase {\n\n  @RemoteServiceRelativePath(\"test\")\n  public interface TestService extends RemoteService {\n    Simple echo(Simple simple);\n\n    SimpleWithBuilder echo(SimpleWithBuilder simple);\n\n    Nested echo(Nested nested);\n\n    NestedWithBuilder echo(NestedWithBuilder nested);\n\n    Generics<Simple> echo(Generics<Simple> generics);\n\n    GenericsWithBuilder<SimpleWithBuilder> echo(GenericsWithBuilder<SimpleWithBuilder> generics);\n  }\n\n  interface TestServiceAsync {\n    void echo(Simple simple, AsyncCallback<Simple> callback);\n\n    void echo(SimpleWithBuilder simple, AsyncCallback<SimpleWithBuilder> callback);\n\n    void echo(Nested nested, AsyncCallback<Nested> callback);\n\n    void echo(NestedWithBuilder nested, AsyncCallback<NestedWithBuilder> callback);\n\n    void echo(Generics<Simple> generics, AsyncCallback<Generics<Simple>> callback);\n\n    void echo(\n        GenericsWithBuilder<SimpleWithBuilder> generics,\n        AsyncCallback<GenericsWithBuilder<SimpleWithBuilder>> callback);\n  }\n\n  class AssertEqualsCallback<T> implements AsyncCallback<T> {\n    private final T expected;\n\n    AssertEqualsCallback(T expected) {\n      this.expected = expected;\n    }\n\n    @Override\n    public void onSuccess(T actual) {\n      assertEquals(expected, actual);\n      finishTest();\n    }\n\n    @Override\n    public void onFailure(Throwable caught) {\n      fail();\n    }\n  }\n\n  @GwtIncompatible(\"RemoteServiceServlet\")\n  @SuppressWarnings(\"serial\")\n  public static class TestServiceImpl extends RemoteServiceServlet implements TestService {\n    @Override\n    public Simple echo(Simple simple) {\n      return Simple.create(simple.message());\n    }\n\n    @Override\n    public SimpleWithBuilder echo(SimpleWithBuilder simple) {\n      return SimpleWithBuilder.builder().message(simple.message()).build();\n    }\n\n    @Override\n    public Nested echo(Nested nested) {\n      return Nested.create(nested.message(), echo(nested.simple()));\n    }\n\n    @Override\n    public NestedWithBuilder echo(NestedWithBuilder nested) {\n      return NestedWithBuilder.builder()\n          .message(nested.message())\n          .simple(echo(nested.simple()))\n          .build();\n    }\n\n    @Override\n    public Generics<Simple> echo(Generics<Simple> generics) {\n      return Generics.create(echo(generics.simple()));\n    }\n\n    @Override\n    public GenericsWithBuilder<SimpleWithBuilder> echo(\n        GenericsWithBuilder<SimpleWithBuilder> generics) {\n      return GenericsWithBuilder.<SimpleWithBuilder>builder()\n          .simple(echo(generics.simple()))\n          .build();\n    }\n  }\n\n  @AutoValue\n  @GwtCompatible(serializable = true)\n  abstract static class Simple {\n    public abstract String message();\n\n    public static Simple create(String message) {\n      return new AutoValue_GwtSerializerTest_Simple(message);\n    }\n  }\n\n  @AutoValue\n  @GwtCompatible(serializable = true)\n  abstract static class SimpleWithBuilder {\n    public abstract String message();\n\n    public static Builder builder() {\n      return new AutoValue_GwtSerializerTest_SimpleWithBuilder.Builder();\n    }\n\n    @AutoValue.Builder\n    public interface Builder {\n      Builder message(String message);\n\n      SimpleWithBuilder build();\n    }\n  }\n\n  @AutoValue\n  @GwtCompatible(serializable = true)\n  abstract static class Nested {\n    public abstract String message();\n\n    public abstract Simple simple();\n\n    public static Nested create(String message, Simple simple) {\n      return new AutoValue_GwtSerializerTest_Nested(message, simple);\n    }\n  }\n\n  @AutoValue\n  @GwtCompatible(serializable = true)\n  abstract static class NestedWithBuilder {\n    public abstract String message();\n\n    public abstract SimpleWithBuilder simple();\n\n    public static Builder builder() {\n      return new AutoValue_GwtSerializerTest_NestedWithBuilder.Builder();\n    }\n\n    @AutoValue.Builder\n    public interface Builder {\n      Builder message(String message);\n\n      Builder simple(SimpleWithBuilder simple);\n\n      NestedWithBuilder build();\n    }\n  }\n\n  @AutoValue\n  @GwtCompatible(serializable = true)\n  abstract static class Generics<T> {\n    public abstract T simple();\n\n    public static <T> Generics<T> create(T simple) {\n      return new AutoValue_GwtSerializerTest_Generics<T>(simple);\n    }\n  }\n\n  @AutoValue\n  @GwtCompatible(serializable = true)\n  abstract static class GenericsWithBuilder<T> {\n    public abstract T simple();\n\n    public static <T> Builder<T> builder() {\n      return new AutoValue_GwtSerializerTest_GenericsWithBuilder.Builder<T>();\n    }\n\n    @AutoValue.Builder\n    public interface Builder<T> {\n      Builder<T> simple(T simple);\n\n      GenericsWithBuilder<T> build();\n    }\n  }\n\n  private TestServiceAsync testService;\n\n  @Override\n  public String getModuleName() {\n    return \"com.google.auto.value.GwtSerializerSuite\";\n  }\n\n  @Override\n  public void gwtSetUp() {\n    testService = GWT.create(TestService.class);\n  }\n\n  public void testSimple() {\n    delayTestFinish(2000);\n    Simple simple = Simple.create(\"able\");\n    testService.echo(simple, new AssertEqualsCallback<Simple>(simple));\n  }\n\n  public void testSimpleWithBuilder() {\n    delayTestFinish(2000);\n    SimpleWithBuilder simple = SimpleWithBuilder.builder().message(\"able\").build();\n    testService.echo(simple, new AssertEqualsCallback<SimpleWithBuilder>(simple));\n  }\n\n  public void testNested() {\n    delayTestFinish(2000);\n    Nested nested = Nested.create(\"able\", Simple.create(\"baker\"));\n    testService.echo(nested, new AssertEqualsCallback<Nested>(nested));\n  }\n\n  public void testNestedWithBuilder() {\n    delayTestFinish(2000);\n    NestedWithBuilder nested =\n        NestedWithBuilder.builder()\n            .message(\"able\")\n            .simple(SimpleWithBuilder.builder().message(\"baker\").build())\n            .build();\n    testService.echo(nested, new AssertEqualsCallback<NestedWithBuilder>(nested));\n  }\n\n  public void testGenerics() {\n    delayTestFinish(2000);\n    Generics<Simple> generics = Generics.create(Simple.create(\"able\"));\n    testService.echo(generics, new AssertEqualsCallback<Generics<Simple>>(generics));\n  }\n\n  public void testGenericsWithBuilder() {\n    delayTestFinish(2000);\n    GenericsWithBuilder<SimpleWithBuilder> generics =\n        GenericsWithBuilder.<SimpleWithBuilder>builder()\n            .simple(SimpleWithBuilder.builder().message(\"able\").build())\n            .build();\n    testService.echo(\n        generics, new AssertEqualsCallback<GenericsWithBuilder<SimpleWithBuilder>>(generics));\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/AutoAnnotation.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\npackage com.google.auto.value;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\nimport java.lang.reflect.AnnotatedElement;\n\n/**\n * Annotation that causes an implementation of an annotation interface to be generated. The\n * annotation is applied to a method whose return type is an annotation interface. The method can\n * then create and return an instance of the generated class that conforms to the specification of\n * {@link Annotation}, in particular as regards {@link Annotation#equals equals} and {@link\n * Annotation#hashCode hashCode}. These instances behave essentially the same as instances returned\n * by {@link AnnotatedElement#getAnnotation}.\n *\n * <p>For example, suppose you have an annotation like this:\n *\n * <pre>{@code\n * package com.google.inject.name;\n *\n * public @interface Named {\n *   String value();\n * }\n * }</pre>\n *\n * <p>You could write a method like this to construct implementations of the interface:\n *\n * <pre>{@code\n * package com.example;\n *\n * public class Names {\n *   @AutoAnnotation public static Named named(String value) {\n *     return new AutoAnnotation_Names_named(value);\n *   }\n * }\n * }</pre>\n *\n * <p>Because the annotated method is called {@code Names.named}, the generated class is called\n * {@code AutoAnnotation_Names_named} in the same package. If the annotated method were in a nested\n * class, for example {@code Outer.Names.named}, then the generated class would be called {@code\n * AutoAnnotation_Outer_Names_named}. The generated class is package-private and it is not expected\n * that it will be referenced outside the {@code @AutoAnnotation} method.\n *\n * <p>The names and types of the parameters in the annotated method must be the same as the names\n * and types of the annotation elements, except that elements which have default values can be\n * omitted. The parameters do not need to be in any particular order.\n *\n * <p>The annotated method does not need to be public. It can have any visibility, including\n * private. This means the method can be a private implementation called by a public method with a\n * different API, for example using a builder.\n *\n * <p>It is a compile-time error if more than one method with the same name in the same class is\n * annotated {@code @AutoAnnotation}.\n *\n * <p>The constructor of the generated class has the same parameters as the {@code @AutoAnnotation}\n * method. It will throw {@code NullPointerException} if any parameter is null. In order to\n * guarantee that the constructed object is immutable, the constructor will clone each array\n * parameter corresponding to an array-valued annotation member, and the implementation of each such\n * member will also return a clone of the array.\n *\n * <p>If your annotation has many elements, you may consider using {@code @AutoBuilder} instead of\n * {@code @AutoAnnotation} to make it easier to construct instances. In that case, {@code default}\n * values from the annotation will become default values for the values in the builder. For example:\n *\n * <pre>{@code\n * class Example {\n *   @interface MyAnnotation {\n *     String name() default \"foo\";\n *     int number() default 23;\n *   }\n *\n *   @AutoBuilder(ofClass = MyAnnotation.class)\n *   interface MyAnnotationBuilder {\n *     MyAnnotationBuilder name(String name);\n *     MyAnnotationBuilder number(int number);\n *     MyAnnotation build();\n *   }\n *\n *   static MyAnnotationBuilder myAnnotationBuilder() {\n *     return new AutoBuilder_Example_MyAnnotationBuilder();\n *   }\n * }\n * }</pre>\n *\n * Here, {@code myAnnotationBuilder().build()} is the same as {@code\n * myAnnotationBuilder().name(\"foo\").number(23).build()} because those are the defaults in the\n * annotation definition.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@Retention(RetentionPolicy.CLASS)\n@Target(ElementType.METHOD)\npublic @interface AutoAnnotation {}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/AutoBuilder.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Specifies that the annotated interface or abstract class should be implemented as a builder.\n *\n * <p>A simple example:\n *\n * <pre>{@code\n * @AutoBuilder(ofClass = Person.class)\n * abstract class PersonBuilder {\n *   static PersonBuilder builder() {\n *     return new AutoBuilder_PersonBuilder();\n *   }\n *\n *   abstract PersonBuilder setName(String name);\n *   abstract PersonBuilder setId(int id);\n *   abstract Person build();\n * }\n * }</pre>\n *\n * @see <a\n *     href=\"https://github.com/google/auto/blob/main/value/userguide/autobuilder.md\">AutoBuilder\n *     User's Guide</a>\n */\n@Retention(RetentionPolicy.CLASS)\n@Target(ElementType.TYPE)\npublic @interface AutoBuilder {\n  /**\n   * The static method from {@link #ofClass} to call when the build-method of the builder is called.\n   * By default this is empty, meaning that a constructor rather than a static method should be\n   * called. There can be more than one method with the given name, or more than one constructor, in\n   * which case the one to call is the one whose parameter names and types correspond to the\n   * abstract methods of the class or interface with the {@code @AutoBuilder} annotation.\n   */\n  String callMethod() default \"\";\n\n  /**\n   * The class or interface containing the constructor or static method that the generated builder\n   * will eventually call. By default this is the class or interface that <i>contains</i> the class\n   * or interface with the {@code @AutoBuilder} annotation.\n   */\n  Class<?> ofClass() default Void.class;\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/AutoOneOf.java",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Specifies that the annotated class is a <em>one-of</em> class, also known as a <a\n * href=\"https://en.wikipedia.org/wiki/Tagged_union\"><em>tagged union</em></a>. An\n * {@code @AutoOneOf} class is very similar to an {@link AutoValue @AutoValue} class, in that its\n * abstract methods define a set of properties. But unlike {@code @AutoValue}, only one of those\n * properties is defined in any given instance.\n *\n * <pre>{@code\n * @AutoOneOf(StringOrInteger.Kind.class)\n * public abstract class StringOrInteger {\n *   public enum Kind {STRING, INTEGER}\n *\n *   public abstract Kind getKind();\n *\n *   public abstract String string();\n *   public abstract int integer();\n *\n *   public static StringOrInteger ofString(String s) {\n *     return AutoOneOf_StringOrInteger.string(s);\n *   }\n *\n *   public static StringOrInteger ofInteger(int i) {\n *     return AutoOneOf_StringOrInteger.integer(i);\n *   }\n * }\n *\n * String client(StringOrInteger stringOrInteger) {\n *   switch (stringOrInteger.getKind()) {\n *     case STRING:\n *       return \"the string '\" + stringOrInteger.string() + \"'\";\n *     case INTEGER:\n *       return \"the integer \" + stringOrInteger.integer();\n *   }\n *   throw new AssertionError();\n * }\n * }</pre>\n *\n * <p>{@code @AutoOneOf} is explained in more detail in the <a\n * href=\"https://github.com/google/auto/blob/main/value/userguide/howto.md#oneof\">user guide</a>.\n *\n * @author Chris Nokleberg\n * @author Éamonn McManus\n */\n@Retention(RetentionPolicy.CLASS)\n@Target(ElementType.TYPE)\npublic @interface AutoOneOf {\n  /** Specifies an enum that has one entry per variant in the one-of. */\n  Class<? extends Enum<?>> value();\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/AutoValue.java",
    "content": "/*\n * Copyright 2012 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\npackage com.google.auto.value;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Specifies that <a href=\"https://github.com/google/auto/tree/main/value\">AutoValue</a> should\n * generate an implementation class for the annotated abstract class, implementing the standard\n * {@link Object} methods like {@link Object#equals equals} to have conventional value semantics. A\n * simple example:\n *\n * <pre>{@code\n * @AutoValue\n * abstract class Person {\n *   static Person create(String name, int id) {\n *     return new AutoValue_Person(name, id);\n *   }\n *\n *   abstract String name();\n *   abstract int id();\n * }\n * }</pre>\n *\n * @see <a href=\"https://github.com/google/auto/tree/main/value\">AutoValue User's Guide</a>\n * @author Éamonn McManus\n * @author Kevin Bourrillion\n */\n@Retention(RetentionPolicy.CLASS)\n@Target(ElementType.TYPE)\npublic @interface AutoValue {\n\n  /**\n   * Specifies that AutoValue should generate an implementation of the annotated class or interface,\n   * to serve as a <i>builder</i> for the value-type class it is nested within. As a simple example,\n   * here is an alternative way to write the {@code Person} class mentioned in the {@link AutoValue}\n   * example:\n   *\n   * <pre>{@code\n   * @AutoValue\n   * abstract class Person {\n   *   static Builder builder() {\n   *     return new AutoValue_Person.Builder();\n   *   }\n   *\n   *   abstract String name();\n   *   abstract int id();\n   *\n   *   @AutoValue.Builder\n   *   interface Builder {\n   *     Builder name(String x);\n   *     Builder id(int x);\n   *     Person build();\n   *   }\n   * }\n   * }</pre>\n   *\n   * @author Éamonn McManus\n   */\n  @Retention(RetentionPolicy.CLASS)\n  @Target(ElementType.TYPE)\n  public @interface Builder {}\n\n  /**\n   * Specifies that AutoValue should copy any annotations from the annotated element to the\n   * generated class. This annotation supports classes and methods.\n   *\n   * <p>The following annotations are excluded:\n   *\n   * <ol>\n   *   <li>AutoValue and its nested annotations;\n   *   <li>any annotation appearing in the {@link AutoValue.CopyAnnotations#exclude} field;\n   *   <li>any class annotation which is itself annotated with the {@link\n   *       java.lang.annotation.Inherited} meta-annotation.\n   * </ol>\n   *\n   * <p>For historical reasons, annotations are always copied from an {@code @AutoValue} property\n   * method to its implementation, unless {@code @CopyAnnotations} is present and explicitly\n   * {@linkplain CopyAnnotations#exclude excludes} that annotation. But annotations are not copied\n   * from the {@code @AutoValue} class itself to its implementation unless {@code @CopyAnnotations}\n   * is present.\n   *\n   * <p>If you want to copy annotations from your {@literal @}AutoValue-annotated class's methods to\n   * the generated fields in the AutoValue_... implementation, annotate your method with\n   * {@literal @}AutoValue.CopyAnnotations. For example, if Example.java is:\n   *\n   * <pre>{@code\n   * @Immutable\n   * @AutoValue\n   * abstract class Example {\n   *   @CopyAnnotations\n   *   @SuppressWarnings(\"Immutable\") // justification ...\n   *   abstract Object getObject();\n   *   // other details ...\n   * }\n   * }</pre>\n   *\n   * <p>Then AutoValue will generate the following AutoValue_Example.java:\n   *\n   * <pre>{@code\n   * final class AutoValue_Example extends Example {\n   *   @SuppressWarnings(\"Immutable\")\n   *   private final Object object;\n   *\n   *   @SuppressWarnings(\"Immutable\")\n   *   @Override\n   *   Object getObject() {\n   *     return object;\n   *   }\n   *\n   *   // other details ...\n   * }\n   * }</pre>\n   *\n   * <p>When the <i>type</i> of an {@code @AutoValue} property method has annotations, those are\n   * part of the type, so by default they are copied to the implementation of the method. But if a\n   * type annotation is mentioned in {@code exclude} then it is not copied.\n   *\n   * <p>For example, suppose {@code @Confidential} is a {@link\n   * java.lang.annotation.ElementType#TYPE_USE TYPE_USE} annotation:\n   *\n   * <pre>{@code\n   * @AutoValue\n   * abstract class Person {\n   *   static Person create(@Confidential String name, int id) {\n   *     return new AutoValue_Person(name, id);\n   *   }\n   *\n   *   abstract @Confidential String name();\n   *   abstract int id();\n   * }\n   * }</pre>\n   *\n   * Then the implementation of the {@code name()} method will also have return type\n   * {@code @Confidential String}. But if {@code name()} were written like this...\n   *\n   * <pre>{@code\n   * @AutoValue.CopyAnnotations(exclude = Confidential.class)\n   * abstract @Confidential String name();\n   * }</pre>\n   *\n   * <p>...then the implementation of {@code name()} would have return type {@code String} without\n   * the annotation.\n   *\n   * @author Carmi Grushko\n   */\n  @Retention(RetentionPolicy.CLASS)\n  @Target({ElementType.TYPE, ElementType.METHOD})\n  public @interface CopyAnnotations {\n    Class<? extends Annotation>[] exclude() default {};\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/AutoValueExtension.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.Set;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.annotation.processing.Processor;\nimport javax.annotation.processing.SupportedOptions;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.TypeMirror;\n\n/**\n * An AutoValueExtension allows for extra functionality to be created during the generation of an\n * AutoValue class.\n *\n * <p>Extensions are discovered at compile time using the {@link java.util.ServiceLoader} APIs,\n * allowing them to run without any additional annotations. To be found by {@code ServiceLoader}, an\n * extension class must be public with a public no-arg constructor, and its fully-qualified name\n * must appear in a file called {@code\n * META-INF/services/com.google.auto.value.extension.AutoValueExtension} in a jar that is on the\n * compiler's {@code -classpath} or {@code -processorpath}.\n *\n * <p>When the AutoValue processor runs for a class {@code Foo}, it will ask each Extension whether\n * it is {@linkplain #applicable applicable}. Suppose two Extensions reply that they are. Then the\n * processor will generate the AutoValue logic in a direct subclass of {@code Foo}, and it will ask\n * the first Extension to generate a subclass of that, and the second Extension to generate a\n * subclass of the subclass. So we might have this hierarchy:\n *\n * <pre>{@code\n * @AutoValue abstract class Foo {...}                          // the hand-written class\n * abstract class $$AutoValue_Foo extends Foo {...}             // generated by AutoValue processor\n * abstract class $AutoValue_Foo extends $$AutoValue_Foo {...}  // generated by first Extension\n * final class AutoValue_Foo extends $AutoValue_Foo {...}       // generated by second Extension\n * }</pre>\n *\n * <p>(The exact naming scheme illustrated here is not fixed and should not be relied on.)\n *\n * <p>If an Extension needs its generated class to be the final class in the inheritance hierarchy,\n * its {@link #mustBeFinal(Context)} method returns true. Only one Extension can return true for a\n * given context. Only generated classes that will be the final class in the inheritance hierarchy\n * can be declared final. All others should be declared abstract.\n *\n * <p>The first generated class in the hierarchy will always be the one generated by the AutoValue\n * processor and the last one will always be the one generated by the Extension that {@code\n * mustBeFinal}, if any. Other than that, the order of the classes in the hierarchy is unspecified.\n * The last class in the hierarchy is {@code AutoValue_Foo} and that is the one that the {@code Foo}\n * class will reference, for example with {@code new AutoValue_Foo(...)}.\n *\n * <p>Each Extension must also be sure to generate a constructor with arguments corresponding to all\n * properties in {@link com.google.auto.value.extension.AutoValueExtension.Context#propertyTypes()},\n * in order, and to call the superclass constructor with the same arguments. This constructor must\n * have at least package visibility.\n *\n * <p>Because the class generated by the AutoValue processor is at the top of the generated\n * hierarchy, Extensions can override its methods, for example {@code hashCode()}, {@code\n * toString()}, or the implementations of the various {@code bar()} property methods.\n */\npublic abstract class AutoValueExtension {\n\n  /** The context of the generation cycle. */\n  public interface Context {\n\n    /**\n     * Returns the processing environment of this generation cycle. This can be used, among other\n     * things, to produce compilation warnings or errors, using {@link\n     * ProcessingEnvironment#getMessager()}.\n     */\n    ProcessingEnvironment processingEnvironment();\n\n    /** Returns the package name of the classes to be generated. */\n    String packageName();\n\n    /**\n     * Returns the annotated class that this generation cycle is based on.\n     *\n     * <p>Given {@code @AutoValue public class Foo {...}}, this will be {@code Foo}.\n     */\n    TypeElement autoValueClass();\n\n    /**\n     * The fully-qualified name of the last class in the {@code AutoValue} hierarchy. For an\n     * {@code @AutoValue} class {@code foo.bar.Baz}, this will be {@code foo.bar.AutoValue_Baz}. The\n     * class may be generated by an extension, which will be the current extension if the {@code\n     * isFinal} parameter to {@link AutoValueExtension#generateClass} is true and the returned\n     * string is not {@code null}.\n     *\n     * <p>For compatibility reasons, this method has a default implementation that throws an\n     * exception. The AutoValue processor supplies an implementation that behaves as documented.\n     */\n    default String finalAutoValueClassName() {\n      throw new UnsupportedOperationException();\n    }\n\n    /**\n     * Returns the ordered collection of properties to be generated by AutoValue. Each key is a\n     * property name, and the corresponding value is the getter method for that property. For\n     * example, if property {@code bar} is defined by {@code abstract String getBar()} then this map\n     * will have an entry mapping {@code \"bar\"} to the {@code ExecutableElement} for {@code\n     * getBar()}.\n     *\n     * <p>To determine the type of a property, it is best to use {@link #propertyTypes()} rather\n     * than looking at the return type of the {@link ExecutableElement} in this map. The reason is\n     * that the final type of the property might be different because of type variables. For\n     * example, if you have...\n     *\n     * <pre>{@code\n     * interface Parent<T> {\n     *   T bar();\n     * }\n     * @AutoValue abstract class Foo implements Parent<String> {...}\n     * }</pre>\n     *\n     * ...then the type of the {@code bar} property in {@code Foo} is actually {@code String}, but\n     * the {@code ExecutableElement} will be the the method in {@code Parent}, whose return type is\n     * {@code T}.\n     */\n    Map<String, ExecutableElement> properties();\n\n    /**\n     * Returns the properties to be generated by AutoValue, with their types. Each key is a property\n     * name, and the corresponding value is the type of that property. The order of the map entries\n     * is the same as the order of the {@code @AutoValue} properties.\n     *\n     * <p>For example, if property {@code bar} is defined by {@code abstract String getBar()} then\n     * this map will have an entry mapping {@code \"bar\"} to the {@code TypeMirror} for {@code\n     * String}.\n     *\n     * <p>For compatibility reasons, this method has a default implementation that throws an\n     * exception. The AutoValue processor supplies an implementation that behaves as documented.\n     */\n    default Map<String, TypeMirror> propertyTypes() {\n      throw new UnsupportedOperationException();\n    }\n\n    /**\n     * Returns the complete set of abstract methods defined in or inherited by the\n     * {@code @AutoValue} class. This includes all methods that define properties (like {@code\n     * abstract String getBar()}), any abstract {@code toBuilder()} method, and any other abstract\n     * method even if it has been consumed by this or another Extension.\n     */\n    Set<ExecutableElement> abstractMethods();\n\n    /**\n     * Returns the complete set of abstract methods defined in or inherited by the {@code @Builder}\n     * class. This includes methods that have been consumed by this or another Extension.\n     *\n     * <p>If there is no builder class, then this set is empty.\n     */\n    Set<ExecutableElement> builderAbstractMethods();\n\n    /**\n     * Returns the complete list of annotations defined on the {@code classToCopyFrom} that should\n     * be added to any generated subclass. Only annotations visible to the {@code @AutoValue} will\n     * be present. See {@link com.google.auto.value.AutoValue.CopyAnnotations\n     * AutoValue.CopyAnnotations} for more information.\n     *\n     * <p>The default implementation of this method returns an empty list for compatibility with\n     * extensions which may have implemented this interface themselves.\n     */\n    default List<AnnotationMirror> classAnnotationsToCopy(TypeElement classToCopyFrom) {\n      return ImmutableList.of();\n    }\n\n    /**\n     * Returns the complete list of annotations defined on the {@code method} that should be applied\n     * to any override of that method. Only annotations visible to the {@code @AutoValue} will be\n     * present. See {@link com.google.auto.value.AutoValue.CopyAnnotations\n     * AutoValue.CopyAnnotations} for more information.\n     *\n     * <p>The default implementation of this method returns an empty list for compatibility with\n     * extensions which may have implemented this interface themselves.\n     */\n    default List<AnnotationMirror> methodAnnotationsToCopy(ExecutableElement method) {\n      return ImmutableList.of();\n    }\n\n    /**\n     * Returns a representation of the {@code Builder} associated with the {@code @AutoValue} class,\n     * if there is one.\n     *\n     * <p>This method returns {@link Optional#empty()} if called from within the {@link #applicable}\n     * method. If an Extension needs {@code Builder} information to decide whether it is applicable,\n     * it should return {@code true} from the {@link #applicable} method and then return {@code\n     * null} from the {@link #generateClass} method if it does not need to generate a class after\n     * all.\n     *\n     * <p>The default implementation of this method returns {@link Optional#empty()} for\n     * compatibility with extensions which may have implemented this interface themselves.\n     */\n    default Optional<BuilderContext> builder() {\n      return Optional.empty();\n    }\n  }\n\n  /** Represents a {@code Builder} associated with an {@code @AutoValue} class. */\n  public interface BuilderContext {\n    /**\n     * Returns the {@code @AutoValue.Builder} interface or abstract class that this object\n     * represents.\n     */\n    TypeElement builderType();\n\n    /**\n     * Returns abstract no-argument methods in the {@code @AutoValue} class that return the builder\n     * type.\n     *\n     * <p>Consider a class like this:\n     *\n     * <pre>{@code\n     * @AutoValue abstract class Foo {\n     *   abstract String bar();\n     *\n     *   abstract Builder toBuilder();\n     *\n     *   ...\n     *   @AutoValue.Builder\n     *   abstract static class Builder {...}\n     * }\n     * }</pre>\n     *\n     * <p>Here {@code toBuilderMethods()} will return a set containing the method {@code\n     * Foo.toBuilder()}.\n     */\n    Set<ExecutableElement> toBuilderMethods();\n\n    /**\n     * Returns static no-argument methods in the {@code @AutoValue} class that return the builder\n     * type.\n     *\n     * <p>Consider a class like this:\n     *\n     * <pre>{@code\n     * @AutoValue abstract class Foo {\n     *   abstract String bar();\n     *\n     *   static Builder builder() {\n     *     return new AutoValue_Foo.Builder()\n     *         .setBar(\"default bar\");\n     *   }\n     *\n     *   @AutoValue.Builder\n     *   abstract class Builder {\n     *     abstract Builder setBar(String x);\n     *     abstract Foo build();\n     *   }\n     * }\n     * }</pre>\n     *\n     * <p>Here {@code builderMethods()} will return a set containing the method {@code\n     * Foo.builder()}. Generated code should usually call this method in preference to constructing\n     * {@code AutoValue_Foo.Builder()} directly, because this method can establish default values\n     * for properties, as it does here.\n     */\n    Set<ExecutableElement> builderMethods();\n\n    /**\n     * Returns the method {@code build()} in the builder class, if it exists and returns the\n     * {@code @AutoValue} type. This is the method that generated code for {@code @AutoValue class\n     * Foo} should call in order to get an instance of {@code Foo} from its builder. The returned\n     * method is called {@code build()}; if the builder uses some other name then extensions have no\n     * good way to guess how they should build.\n     *\n     * <p>A common convention is for {@code build()} to be a concrete method in the\n     * {@code @AutoValue.Builder} class, which calls an abstract method {@code autoBuild()} that is\n     * implemented in the generated subclass. The {@code build()} method can then do validation,\n     * defaulting, and so on.\n     */\n    Optional<ExecutableElement> buildMethod();\n\n    /**\n     * Returns the abstract build method. If the {@code @AutoValue} class is {@code Foo}, this is an\n     * abstract no-argument method in the builder class that returns {@code Foo}. This might be\n     * called {@code build()}, or, following a common convention, it might be called {@code\n     * autoBuild()} and used in the implementation of a {@code build()} method that is defined in\n     * the builder class.\n     *\n     * <p>Extensions should call the {@code build()} method in preference to this one. But they\n     * should override this one if they want to customize build-time behaviour.\n     */\n    ExecutableElement autoBuildMethod();\n\n    /**\n     * Returns a map from property names to the corresponding setters. A property may have more than\n     * one setter. For example, an {@code ImmutableList<String>} might be set by {@code\n     * setFoo(ImmutableList<String>)} and {@code setFoo(String[])}.\n     */\n    Map<String, Set<ExecutableElement>> setters();\n\n    /**\n     * Returns a map from property names to property builders. For example, if there is a property\n     * {@code foo} defined by {@code abstract ImmutableList<String> foo();} or {@code abstract\n     * ImmutableList<String> getFoo();} in the {@code @AutoValue} class, then there can potentially\n     * be a builder defined by {@code abstract ImmutableList.Builder<String> fooBuilder();} in the\n     * {@code @AutoValue.Builder} class. This map would then map {@code \"foo\"} to the {@link\n     * ExecutableElement} representing {@code fooBuilder()}.\n     */\n    Map<String, ExecutableElement> propertyBuilders();\n  }\n\n  /**\n   * Indicates to an annotation processor environment supporting incremental annotation processing\n   * (currently a feature specific to Gradle starting with version 4.8) the incremental type of an\n   * Extension.\n   *\n   * <p>The constants for this enum are ordered by increasing performance (but also constraints).\n   *\n   * @see <a\n   *     href=\"https://docs.gradle.org/current/userguide/java_plugin.html#sec:incremental_annotation_processing\">Gradle\n   *     documentation of its incremental annotation processing</a>\n   */\n  public enum IncrementalExtensionType {\n    /**\n     * The incrementality of this extension is unknown, or it is neither aggregating nor isolating.\n     */\n    UNKNOWN,\n\n    /**\n     * This extension is <i>aggregating</i>, meaning that it may generate outputs based on several\n     * annotated input classes and it respects the constraints imposed on aggregating processors. It\n     * is unusual for AutoValue extensions to be aggregating.\n     *\n     * @see <a\n     *     href=\"https://docs.gradle.org/current/userguide/java_plugin.html#aggregating_annotation_processors\">Gradle\n     *     definition of aggregating processors</a>\n     */\n    AGGREGATING,\n\n    /**\n     * This extension is <i>isolating</i>, meaning roughly that its output depends on the\n     * {@code @AutoValue} class and its dependencies, but not on other {@code @AutoValue} classes\n     * that might be compiled at the same time. The constraints that an isolating extension must\n     * respect are the same as those that Gradle imposes on an isolating annotation processor.\n     *\n     * @see <a\n     *     href=\"https://docs.gradle.org/current/userguide/java_plugin.html#isolating_annotation_processors\">Gradle\n     *     definition of isolating processors</a>\n     */\n    ISOLATING\n  }\n\n  /**\n   * Determines the incremental type of this Extension.\n   *\n   * <p>The {@link ProcessingEnvironment} can be used, among other things, to obtain the processor\n   * options, using {@link ProcessingEnvironment#getOptions()}.\n   *\n   * <p>The actual incremental type of the AutoValue processor as a whole will be the loosest\n   * incremental types of the Extensions present in the annotation processor path. The default\n   * returned value is {@link IncrementalExtensionType#UNKNOWN}, which will disable incremental\n   * annotation processing entirely.\n   */\n  public IncrementalExtensionType incrementalType(ProcessingEnvironment processingEnvironment) {\n    return IncrementalExtensionType.UNKNOWN;\n  }\n\n  /**\n   * Analogous to {@link Processor#getSupportedOptions()}, here to allow extensions to report their\n   * own.\n   *\n   * <p>By default, if the extension class is annotated with {@link SupportedOptions}, this will\n   * return a set with the strings in the annotation. If the class is not so annotated, an empty set\n   * is returned.\n   *\n   * @return the set of options recognized by this extension or an empty set if none\n   * @see SupportedOptions\n   */\n  public Set<String> getSupportedOptions() {\n    SupportedOptions so = this.getClass().getAnnotation(SupportedOptions.class);\n    if (so == null) {\n      return ImmutableSet.of();\n    } else {\n      return ImmutableSet.copyOf(so.value());\n    }\n  }\n\n  /**\n   * Determines whether this Extension applies to the given context. If an Extension returns {@code\n   * false} for a given class, it will not be called again during the processing of that class. An\n   * Extension can return {@code true} and still choose not to generate any code for the class, by\n   * returning {@code null} from {@link #generateClass}. That is often a more flexible approach.\n   *\n   * @param context The Context of the code generation for this class.\n   */\n  public boolean applicable(Context context) {\n    return false;\n  }\n\n  /**\n   * Denotes that the class generated by this Extension must be the final class in the inheritance\n   * hierarchy. Only one Extension may be the final class, so this should be used sparingly.\n   *\n   * @param context the Context of the code generation for this class.\n   */\n  public boolean mustBeFinal(Context context) {\n    return false;\n  }\n\n  /**\n   * Returns a possibly empty set of property names that this Extension intends to implement. This\n   * will prevent AutoValue from generating an implementation, and remove the supplied properties\n   * from builders, constructors, {@code toString}, {@code equals}, and {@code hashCode}. The\n   * default set returned by this method is empty.\n   *\n   * <p>Each returned string must be one of the property names in {@link Context#properties()}.\n   *\n   * <p>Returning a property name from this method is equivalent to returning the property's getter\n   * method from {@link #consumeMethods}.\n   *\n   * <p>For example, Android's {@code Parcelable} interface includes a <a\n   * href=\"http://developer.android.com/reference/android/os/Parcelable.html#describeContents()\">method</a>\n   * {@code int describeContents()}. Since this is an abstract method with no parameters, by default\n   * AutoValue will consider that it defines an {@code int} property called {@code\n   * describeContents}. If an {@code @AutoValue} class implements {@code Parcelable} and does not\n   * provide an implementation of this method, by default its implementation will include {@code\n   * describeContents} in builders, constructors, and so on. But an {@code AutoValueExtension} that\n   * understands {@code Parcelable} can instead provide a useful implementation and return a set\n   * containing {@code \"describeContents\"}. Then {@code describeContents} will be omitted from\n   * builders and the rest.\n   *\n   * @param context the Context of the code generation for this class.\n   */\n  public Set<String> consumeProperties(Context context) {\n    return ImmutableSet.of();\n  }\n\n  /**\n   * Returns a possibly empty set of abstract methods that this Extension intends to implement. This\n   * will prevent AutoValue from generating an implementation, in cases where it would have, and it\n   * will also avoid complaints about abstract methods that AutoValue doesn't expect. The default\n   * set returned by this method is empty.\n   *\n   * <p>Each returned method must be one of the abstract methods in {@link\n   * Context#abstractMethods()}.\n   *\n   * <p>For example, Android's {@code Parcelable} interface includes a <a\n   * href=\"http://developer.android.com/reference/android/os/Parcelable.html#writeToParcel(android.os.Parcel,int)\">method</a>\n   * {@code void writeToParcel(Parcel, int)}. Normally AutoValue would not know what to do with that\n   * abstract method. But an {@code AutoValueExtension} that understands {@code Parcelable} can\n   * provide a useful implementation and return the {@code writeToParcel} method here. That will\n   * prevent a warning about the method from AutoValue.\n   *\n   * @param context the Context of the code generation for this class.\n   */\n  public Set<ExecutableElement> consumeMethods(Context context) {\n    return ImmutableSet.of();\n  }\n\n  /**\n   * Returns a possibly empty set of abstract methods that this Extension intends to implement. This\n   * will prevent AutoValue from generating an implementation, in cases where it would have, and it\n   * will also avoid complaints about abstract methods that AutoValue doesn't expect. The default\n   * set returned by this method is empty.\n   *\n   * <p>Each returned method must be one of the abstract methods in {@link\n   * Context#builderAbstractMethods()}.\n   *\n   * @param context the Context of the code generation for this class.\n   */\n  public Set<ExecutableElement> consumeBuilderMethods(Context context) {\n    return ImmutableSet.of();\n  }\n\n  /**\n   * Returns the generated source code of the class named {@code className} to extend {@code\n   * classToExtend}, or {@code null} if this extension does not generate a class in the hierarchy.\n   * If there is a generated class, it should be final if {@code isFinal} is true; otherwise it\n   * should be abstract. The returned string should be a complete Java class definition of the class\n   * {@code className} in the package {@link Context#packageName() context.packageName()}.\n   *\n   * <p>The returned string will typically look like this:\n   *\n   * <pre>{@code\n   * package <package>;\n   * ...\n   * <finalOrAbstract> class <className> extends <classToExtend> {\n   *   // Constructor\n   *   <className>(<constructorParameters>) {\n   *     super(<constructorParameterNames>);\n   *     ...\n   *   }\n   *   ...\n   * }\n   * }</pre>\n   *\n   * <p>Here, {@code <package>} is {@link Context#packageName()}; {@code <finalOrAbstract>} is the\n   * keyword {@code final} if {@code isFinal} is true or {@code abstract} otherwise; and {@code\n   * <className>} and {@code <classToExtend>} are the values of this method's parameters of the same\n   * name. The {@code <constructorParameters>} and {@code <constructorParameterNames>} are typically\n   * derived from {@link Context#propertyTypes()}.\n   *\n   * <p>An extension can also generate a subclass of the nested {@code Builder} class if there is\n   * one. In that case, it should check if {@link BuilderContext#toBuilderMethods()} is empty. If\n   * not, the {@code Builder} subclass should include a \"copy constructor\", like this:\n   *\n   * <pre>{@code\n   * ...\n   * <finalOrAbstract> class <className> extends <classToExtend> {\n   *   ...\n   *   static class Builder extends <classToExtend>.Builder {\n   *     Builder() {}\n   *     Builder(<autoValueClass> copyFrom) {\n   *       super(copyFrom);\n   *     }\n   *     ...\n   *   }\n   * }\n   * }</pre>\n   *\n   * <p>Here, {@code <autoValueClass>} is {@link Context#autoValueClass()}.}\n   *\n   * @param context The {@link Context} of the code generation for this class.\n   * @param className The simple name of the resulting class. The returned code will be written to a\n   *     file named accordingly.\n   * @param classToExtend The simple name of the direct parent of the generated class. This could be\n   *     the AutoValue generated class, or a class generated as the result of another Extension.\n   * @param isFinal True if this class is the last class in the chain, meaning it should be marked\n   *     as final. Otherwise it should be marked as abstract.\n   * @return The source code of the generated class, or {@code null} if this extension does not\n   *     generate a class in the hierarchy.\n   */\n  public abstract String generateClass(\n      Context context, String className, String classToExtend, boolean isFinal);\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/memoized/Memoized.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.memoized;\n\nimport static java.lang.annotation.ElementType.METHOD;\nimport static java.lang.annotation.RetentionPolicy.CLASS;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\n/**\n * Annotates methods in {@link com.google.auto.value.AutoValue @AutoValue} classes for which the\n * generated subclass will <a href=\"https://en.wikipedia.org/wiki/Memoization\">memoize</a> the\n * returned value.\n *\n * <p>Methods annotated with {@code @Memoized} cannot:\n *\n * <ul>\n *   <li>be {@code abstract} (except for {@link #hashCode()} and {@link #toString()}), {@code\n *       private}, {@code final}, or {@code static}\n *   <li>return {@code void}\n *   <li>have any parameters\n * </ul>\n *\n * <p>If you want to memoize {@link #hashCode()} or {@link #toString()}, you can redeclare them,\n * keeping them {@code abstract}, and annotate them with {@code @Memoized}.\n *\n * <p>If a {@code @Memoized} method is annotated with an annotation whose simple name is {@code\n * Nullable}, then {@code null} values will also be memoized. Otherwise, if the method returns\n * {@code null}, the overriding method will throw a {@link NullPointerException}.\n *\n * <p>The overriding method uses <a\n * href=\"https://errorprone.info/bugpattern/DoubleCheckedLocking\">double-checked locking</a> to\n * ensure that the annotated method is called at most once.\n *\n * <h2>Example</h2>\n *\n * <pre>{@code\n * @AutoValue\n * abstract class Value {\n *   abstract String stringProperty();\n *\n *   @Memoized\n *   String derivedProperty() {\n *     return someCalculationOn(stringProperty());\n *   }\n * }\n *\n * @Generated\n * class AutoValue_Value {\n *   // …\n *\n *   private volatile String derivedProperty;\n *\n *   @Override\n *   String derivedProperty() {\n *     if (derivedProperty == null) {\n *       synchronized (this) {\n *         if (derivedProperty == null) {\n *           derivedProperty = super.derivedProperty();\n *         }\n *       }\n *     }\n *     return derivedProperty;\n *   }\n * }\n * }</pre>\n */\n@Documented\n@Retention(CLASS)\n@Target(METHOD)\npublic @interface Memoized {}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/memoized/processor/ClassNames.java",
    "content": "/*\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.memoized.processor;\n\n/** Names of classes that are referenced in the processor/extension. */\nfinal class ClassNames {\n  static final String MEMOIZED_NAME = \"com.google.auto.value.extension.memoized.Memoized\";\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/memoized/processor/MemoizeExtension.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.memoized.processor;\n\nimport static com.google.auto.common.GeneratedAnnotationSpecs.generatedAnnotationSpec;\nimport static com.google.auto.value.extension.memoized.processor.ClassNames.MEMOIZED_NAME;\nimport static com.google.auto.value.extension.memoized.processor.MemoizedValidator.getAnnotationMirror;\nimport static com.google.common.base.Predicates.equalTo;\nimport static com.google.common.base.Predicates.not;\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static com.google.common.collect.ImmutableMap.toImmutableMap;\nimport static com.google.common.collect.ImmutableSet.toImmutableSet;\nimport static com.google.common.collect.Iterables.filter;\nimport static com.google.common.collect.Iterables.getOnlyElement;\nimport static com.squareup.javapoet.MethodSpec.constructorBuilder;\nimport static com.squareup.javapoet.MethodSpec.methodBuilder;\nimport static com.squareup.javapoet.TypeSpec.classBuilder;\nimport static java.util.stream.Collectors.joining;\nimport static java.util.stream.Collectors.toList;\nimport static javax.lang.model.element.Modifier.ABSTRACT;\nimport static javax.lang.model.element.Modifier.FINAL;\nimport static javax.lang.model.element.Modifier.PRIVATE;\nimport static javax.lang.model.element.Modifier.PUBLIC;\nimport static javax.lang.model.element.Modifier.STATIC;\nimport static javax.lang.model.element.Modifier.TRANSIENT;\nimport static javax.lang.model.element.Modifier.VOLATILE;\nimport static javax.lang.model.type.TypeKind.VOID;\nimport static javax.lang.model.util.ElementFilter.methodsIn;\nimport static javax.tools.Diagnostic.Kind.ERROR;\n\nimport com.google.auto.common.MoreElements;\nimport com.google.auto.service.AutoService;\nimport com.google.auto.value.extension.AutoValueExtension;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.errorprone.annotations.FormatMethod;\nimport com.squareup.javapoet.AnnotationSpec;\nimport com.squareup.javapoet.ClassName;\nimport com.squareup.javapoet.CodeBlock;\nimport com.squareup.javapoet.FieldSpec;\nimport com.squareup.javapoet.JavaFile;\nimport com.squareup.javapoet.MethodSpec;\nimport com.squareup.javapoet.ParameterizedTypeName;\nimport com.squareup.javapoet.TypeName;\nimport com.squareup.javapoet.TypeSpec;\nimport com.squareup.javapoet.TypeVariableName;\nimport java.util.List;\nimport java.util.Optional;\nimport java.util.Set;\nimport javax.annotation.processing.Messager;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.Modifier;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.Types;\nimport javax.tools.Diagnostic.Kind;\n\n/**\n * An extension that implements the {@link com.google.auto.value.extension.memoized.Memoized}\n * contract.\n */\n@AutoService(AutoValueExtension.class)\npublic final class MemoizeExtension extends AutoValueExtension {\n  private static final ImmutableSet<String> DO_NOT_PULL_DOWN_ANNOTATIONS =\n      ImmutableSet.of(Override.class.getCanonicalName(), MEMOIZED_NAME);\n\n  // Maven is configured to shade (rewrite) com.google packages to prevent dependency conflicts.\n  // Split up the package here with a call to concat to prevent Maven from finding and rewriting it,\n  // so that this will be able to find the LazyInit annotation if it's on the classpath.\n  private static final ClassName LAZY_INIT =\n      ClassName.get(\"com\".concat(\".google.errorprone.annotations.concurrent\"), \"LazyInit\");\n\n  private static final AnnotationSpec SUPPRESS_WARNINGS =\n      AnnotationSpec.builder(SuppressWarnings.class).addMember(\"value\", \"$S\", \"Immutable\").build();\n\n  @Override\n  public IncrementalExtensionType incrementalType(ProcessingEnvironment processingEnvironment) {\n    return IncrementalExtensionType.ISOLATING;\n  }\n\n  @Override\n  public boolean applicable(Context context) {\n    return !memoizedMethods(context).isEmpty();\n  }\n\n  @Override\n  public String generateClass(\n      Context context, String className, String classToExtend, boolean isFinal) {\n    return new Generator(context, className, classToExtend, isFinal).generate();\n  }\n\n  private static ImmutableSet<ExecutableElement> memoizedMethods(Context context) {\n    return methodsIn(context.autoValueClass().getEnclosedElements()).stream()\n        .filter(m -> getAnnotationMirror(m, MEMOIZED_NAME).isPresent())\n        .collect(toImmutableSet());\n  }\n\n  static final class Generator {\n    private final Context context;\n    private final String className;\n    private final String classToExtend;\n    private final boolean isFinal;\n    private final Elements elements;\n    private final Types types;\n    private final SourceVersion sourceVersion;\n    private final Messager messager;\n    private final Optional<AnnotationSpec> lazyInitAnnotation;\n    private boolean hasErrors;\n\n    Generator(Context context, String className, String classToExtend, boolean isFinal) {\n      this.context = context;\n      this.className = className;\n      this.classToExtend = classToExtend;\n      this.isFinal = isFinal;\n      this.elements = context.processingEnvironment().getElementUtils();\n      this.types = context.processingEnvironment().getTypeUtils();\n      this.sourceVersion = context.processingEnvironment().getSourceVersion();\n      this.messager = context.processingEnvironment().getMessager();\n      this.lazyInitAnnotation = getLazyInitAnnotation(elements);\n    }\n\n    String generate() {\n\n      TypeSpec.Builder generated =\n          classBuilder(className)\n              .superclass(superType())\n              .addAnnotations(\n                  context.classAnnotationsToCopy(context.autoValueClass()).stream()\n                      .map(AnnotationSpec::get)\n                      .collect(toImmutableList()))\n              .addTypeVariables(annotatedTypeVariableNames())\n              .addModifiers(isFinal ? FINAL : ABSTRACT)\n              .addMethod(constructor());\n      generatedAnnotationSpec(elements, sourceVersion, MemoizeExtension.class)\n          .ifPresent(generated::addAnnotation);\n\n      for (ExecutableElement method : memoizedMethods(context)) {\n        MethodOverrider methodOverrider = new MethodOverrider(method);\n        generated.addFields(methodOverrider.fields());\n        generated.addMethod(methodOverrider.method());\n      }\n      if (isHashCodeMemoized() && !isEqualsFinal()) {\n        generated.addMethod(equalsWithHashCodeCheck());\n      }\n      if (hasErrors) {\n        return null;\n      }\n      return JavaFile.builder(context.packageName(), generated.build()).build().toString();\n    }\n\n\n    private TypeName superType() {\n      ClassName superType = ClassName.get(context.packageName(), classToExtend);\n      ImmutableList<TypeVariableName> typeVariableNames = typeVariableNames();\n\n      return typeVariableNames.isEmpty()\n          ? superType\n          : ParameterizedTypeName.get(superType, typeVariableNames.toArray(new TypeName[] {}));\n    }\n\n    private ImmutableList<TypeVariableName> typeVariableNames() {\n      return context.autoValueClass().getTypeParameters().stream()\n          .map(TypeVariableName::get)\n          .collect(toImmutableList());\n    }\n\n    private ImmutableList<TypeVariableName> annotatedTypeVariableNames() {\n      return context.autoValueClass().getTypeParameters().stream()\n          .map(\n              p ->\n                  TypeVariableName.get(p)\n                      .annotated(\n                          p.getAnnotationMirrors().stream()\n                              .map(AnnotationSpec::get)\n                              .collect(toImmutableList())))\n          .collect(toImmutableList());\n    }\n\n    private MethodSpec constructor() {\n      MethodSpec.Builder constructor = constructorBuilder();\n      // TODO(b/35944623): Replace this with a standard way of avoiding keywords.\n      Set<String> propertyNames = context.properties().keySet();\n      ImmutableMap<String, String> parameterNames =\n          propertyNames.stream()\n              .collect(\n                  toImmutableMap(name -> name, name -> generateIdentifier(name, propertyNames)));\n      context\n          .propertyTypes()\n          .forEach(\n              (name, type) ->\n                  constructor.addParameter(annotatedType(type), parameterNames.get(name)));\n      String superParams =\n          context.properties().keySet().stream().map(parameterNames::get).collect(joining(\", \"));\n      constructor.addStatement(\"super($L)\", superParams);\n      return constructor.build();\n    }\n\n    private static String generateIdentifier(String name, Set<String> existingNames) {\n      if (!SourceVersion.isKeyword(name)) {\n        return name;\n      }\n      for (int i = 0; ; i++) {\n        String newName = name + i;\n        if (!existingNames.contains(newName)) {\n          return newName;\n        }\n      }\n    }\n\n\n\n    private boolean isHashCodeMemoized() {\n      return memoizedMethods(context).stream()\n          .anyMatch(method -> method.getSimpleName().contentEquals(\"hashCode\"));\n    }\n\n    private boolean isEqualsFinal() {\n      TypeMirror objectType = elements.getTypeElement(Object.class.getCanonicalName()).asType();\n      ExecutableElement equals =\n          MoreElements.getLocalAndInheritedMethods(context.autoValueClass(), types, elements)\n              .stream()\n              .filter(method -> method.getSimpleName().contentEquals(\"equals\"))\n              .filter(method -> method.getParameters().size() == 1)\n              .filter(\n                  method ->\n                      types.isSameType(getOnlyElement(method.getParameters()).asType(), objectType))\n              .findFirst()\n              .get();\n      return equals.getModifiers().contains(FINAL);\n    }\n\n    private MethodSpec equalsWithHashCodeCheck() {\n      return methodBuilder(\"equals\")\n          .addModifiers(PUBLIC)\n          .returns(TypeName.BOOLEAN)\n          .addAnnotation(Override.class)\n          .addParameter(TypeName.OBJECT, \"that\")\n          .beginControlFlow(\"if (this == that)\")\n          .addStatement(\"return true\")\n          .endControlFlow()\n          .addStatement(\n              \"return that instanceof $N \"\n                  + \"&& this.hashCode() == that.hashCode() \"\n                  + \"&& super.equals(that)\",\n              className)\n          .build();\n    }\n\n    /**\n     * Determines the required fields and overriding method for a {@link\n     * com.google.auto.value.extension.memoized.Memoized @Memoized} method.\n     */\n    private final class MethodOverrider {\n      private final ExecutableElement method;\n      private final MethodSpec.Builder override;\n      private final FieldSpec cacheField;\n      private final ImmutableList.Builder<FieldSpec> fields = ImmutableList.builder();\n\n      MethodOverrider(ExecutableElement method) {\n        this.method = method;\n        validate();\n        cacheField =\n            buildCacheField(\n                annotatedType(method.getReturnType()), method.getSimpleName().toString());\n        fields.add(cacheField);\n        override =\n            methodBuilder(method.getSimpleName().toString())\n                .addAnnotation(Override.class)\n                .returns(cacheField.type)\n                .addExceptions(\n                    method.getThrownTypes().stream().map(TypeName::get).collect(toList()))\n                .addModifiers(filter(method.getModifiers(), not(equalTo(ABSTRACT))));\n        for (AnnotationMirror annotation : context.methodAnnotationsToCopy(method)) {\n          AnnotationSpec annotationSpec = AnnotationSpec.get(annotation);\n          if (pullDownMethodAnnotation(annotation)) {\n            override.addAnnotation(annotationSpec);\n          }\n        }\n\n        InitializationStrategy checkStrategy = strategy();\n        fields.addAll(checkStrategy.additionalFields());\n        override\n            .beginControlFlow(\"if ($L)\", checkStrategy.checkMemoized())\n            .beginControlFlow(\"synchronized (this)\")\n            .beginControlFlow(\"if ($L)\", checkStrategy.checkMemoized())\n            .addStatement(\"$N = super.$L()\", cacheField, method.getSimpleName())\n            .addCode(checkStrategy.setMemoized())\n            .endControlFlow()\n            .endControlFlow()\n            .endControlFlow()\n            .addStatement(\"return $N\", cacheField);\n      }\n\n      /** The fields that should be added to the subclass. */\n      Iterable<FieldSpec> fields() {\n        return fields.build();\n      }\n\n      /** The overriding method that should be added to the subclass. */\n      MethodSpec method() {\n        return override.build();\n      }\n\n      private void validate() {\n        if (method.getReturnType().getKind().equals(VOID)) {\n          printMessage(ERROR, \"@Memoized methods cannot be void\");\n        }\n        if (!method.getParameters().isEmpty()) {\n          printMessage(ERROR, \"@Memoized methods cannot have parameters\");\n        }\n        checkIllegalModifier(PRIVATE);\n        checkIllegalModifier(FINAL);\n        checkIllegalModifier(STATIC);\n\n        if (!overridesObjectMethod(\"hashCode\") && !overridesObjectMethod(\"toString\")) {\n          checkIllegalModifier(ABSTRACT);\n        }\n      }\n\n      private void checkIllegalModifier(Modifier modifier) {\n        if (method.getModifiers().contains(modifier)) {\n          printMessage(ERROR, \"@Memoized methods cannot be %s\", modifier.toString());\n        }\n      }\n\n      @FormatMethod\n      private void printMessage(Kind kind, String format, Object... args) {\n        if (kind.equals(ERROR)) {\n          hasErrors = true;\n        }\n        messager.printMessage(kind, String.format(format, args), method);\n      }\n\n      private boolean overridesObjectMethod(String methodName) {\n        return elements.overrides(method, objectMethod(methodName), context.autoValueClass());\n      }\n\n      private ExecutableElement objectMethod(String methodName) {\n        TypeElement object = elements.getTypeElement(Object.class.getName());\n        return methodsIn(object.getEnclosedElements()).stream()\n            .filter(m -> m.getSimpleName().contentEquals(methodName))\n            .findFirst()\n            .orElseThrow(\n                () ->\n                    new IllegalArgumentException(\n                        String.format(\"No method in Object named \\\"%s\\\"\", methodName)));\n      }\n\n      private boolean pullDownMethodAnnotation(AnnotationMirror annotation) {\n        return !DO_NOT_PULL_DOWN_ANNOTATIONS.contains(\n            MoreElements.asType(annotation.getAnnotationType().asElement())\n                .getQualifiedName()\n                .toString());\n      }\n\n      /**\n       * Builds a {@link FieldSpec} for use in property caching. Field will be {@code private\n       * transient volatile} and have the given type and name. If the @LazyInit annotation is\n       * available it is added as well.\n       */\n      private FieldSpec buildCacheField(TypeName type, String name) {\n        FieldSpec.Builder builder = FieldSpec.builder(type, name, PRIVATE, TRANSIENT, VOLATILE);\n        if (lazyInitAnnotation.isPresent()) {\n          builder.addAnnotation(lazyInitAnnotation.get());\n          builder.addAnnotation(SUPPRESS_WARNINGS);\n        }\n        return builder.build();\n      }\n\n      InitializationStrategy strategy() {\n        if (method.getReturnType().getKind().isPrimitive()) {\n          return new CheckBooleanField();\n        }\n        if (containsNullable(method.getAnnotationMirrors())\n            || containsNullable(method.getReturnType().getAnnotationMirrors())) {\n          return new CheckBooleanField();\n        }\n        return new NullMeansUninitialized();\n      }\n\n      private abstract class InitializationStrategy {\n\n        abstract Iterable<FieldSpec> additionalFields();\n\n        abstract CodeBlock checkMemoized();\n\n        abstract CodeBlock setMemoized();\n      }\n\n      private final class NullMeansUninitialized extends InitializationStrategy {\n        @Override\n        Iterable<FieldSpec> additionalFields() {\n          return ImmutableList.of();\n        }\n\n        @Override\n        CodeBlock checkMemoized() {\n          return CodeBlock.of(\"$N == null\", cacheField);\n        }\n\n        @Override\n        CodeBlock setMemoized() {\n          return CodeBlock.builder()\n              .beginControlFlow(\"if ($N == null)\", cacheField)\n              .addStatement(\n                  \"throw new NullPointerException($S)\",\n                  method.getSimpleName() + \"() cannot return null\")\n              .endControlFlow()\n              .build();\n        }\n      }\n\n      private final class CheckBooleanField extends InitializationStrategy {\n\n        private final FieldSpec field =\n            buildCacheField(TypeName.BOOLEAN, method.getSimpleName() + \"$Memoized\");\n\n        @Override\n        Iterable<FieldSpec> additionalFields() {\n          return ImmutableList.of(field);\n        }\n\n        @Override\n        CodeBlock checkMemoized() {\n          return CodeBlock.of(\"!$N\", field);\n        }\n\n        @Override\n        CodeBlock setMemoized() {\n          return CodeBlock.builder().addStatement(\"$N = true\", field).build();\n        }\n      }\n    }\n  }\n\n  /** Returns the errorprone {@code @LazyInit} annotation if it is found on the classpath. */\n  private static Optional<AnnotationSpec> getLazyInitAnnotation(Elements elements) {\n    if (elements.getTypeElement(LAZY_INIT.toString()) == null) {\n      return Optional.empty();\n    }\n    return Optional.of(AnnotationSpec.builder(LAZY_INIT).build());\n  }\n\n  /** True if one of the given annotations is {@code @Nullable} in any package. */\n  private static boolean containsNullable(List<? extends AnnotationMirror> annotations) {\n    return annotations.stream()\n        .map(a -> a.getAnnotationType().asElement().getSimpleName())\n        .anyMatch(n -> n.contentEquals(\"Nullable\"));\n  }\n\n\n  /** Translate a {@link TypeMirror} into a {@link TypeName}, including type annotations. */\n  private static TypeName annotatedType(TypeMirror type) {\n    List<AnnotationSpec> annotations =\n        type.getAnnotationMirrors().stream().map(AnnotationSpec::get).collect(toList());\n    return TypeName.get(type).annotated(annotations);\n  }\n\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/memoized/processor/MemoizedValidator.java",
    "content": "/*\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.memoized.processor;\n\nimport static com.google.auto.value.extension.memoized.processor.ClassNames.MEMOIZED_NAME;\nimport static javax.lang.model.util.ElementFilter.methodsIn;\nimport static javax.tools.Diagnostic.Kind.ERROR;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.service.AutoService;\nimport java.util.Optional;\nimport java.util.Set;\nimport javax.annotation.processing.AbstractProcessor;\nimport javax.annotation.processing.Messager;\nimport javax.annotation.processing.Processor;\nimport javax.annotation.processing.RoundEnvironment;\nimport javax.annotation.processing.SupportedAnnotationTypes;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessor;\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;\n\n/**\n * An annotation {@link Processor} that reports errors for {@code @Memoized} methods that are not\n * inside {@code AutoValue}-annotated classes.\n */\n@AutoService(Processor.class)\n@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.ISOLATING)\n@SupportedAnnotationTypes(MEMOIZED_NAME)\npublic final class MemoizedValidator extends AbstractProcessor {\n  @Override\n  public final boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n    Messager messager = processingEnv.getMessager();\n    TypeElement memoized = processingEnv.getElementUtils().getTypeElement(MEMOIZED_NAME);\n    for (ExecutableElement method : methodsIn(roundEnv.getElementsAnnotatedWith(memoized))) {\n      if (!isAutoValue(method.getEnclosingElement())) {\n        messager.printMessage(\n            ERROR,\n            \"@Memoized methods must be declared only in @AutoValue classes\",\n            method,\n            getAnnotationMirror(method, MEMOIZED_NAME).get());\n      }\n    }\n    return false;\n  }\n\n  @Override\n  public SourceVersion getSupportedSourceVersion() {\n    return SourceVersion.latestSupported();\n  }\n\n  private static boolean isAutoValue(Element element) {\n    return element.getAnnotationMirrors().stream()\n        .map(annotation -> MoreTypes.asTypeElement(annotation.getAnnotationType()))\n        .anyMatch(type -> type.getQualifiedName().contentEquals(\"com.google.auto.value.AutoValue\"));\n  }\n\n  static Optional<AnnotationMirror> getAnnotationMirror(Element element, String annotationName) {\n    for (AnnotationMirror annotation : element.getAnnotationMirrors()) {\n      TypeElement annotationElement = MoreTypes.asTypeElement(annotation.getAnnotationType());\n      if (annotationElement.getQualifiedName().contentEquals(annotationName)) {\n        return Optional.of(annotation);\n      }\n    }\n    return Optional.empty();\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/serializable/SerializableAutoValue.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Annotates {@link com.google.auto.value.AutoValue @AutoValue} classes that implement {@link\n * java.io.Serializable}. A serializable subclass is generated for classes with normally\n * un-serializable fields like {@link java.util.Optional}.\n */\n@Retention(RetentionPolicy.SOURCE)\n@Target(ElementType.TYPE)\npublic @interface SerializableAutoValue {}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/serializable/g3doc/index.md",
    "content": "# Serializable AutoValue Extension\n\n\nAn [`AutoValue`] extension that enables `@AutoValue` classes with\nun-serializable properties to be serializable.\n\n## Usage\n\nTo use the [`SerializableAutoValueExtension`] with your `AutoValue` class, the\n`AutoValue` class must:\n\n1.  Implement `java.io.Serializable`.\n2.  Be annotated with `@SerializableAutoValue`.\n\n## Example\n\nThe following `AutoValue` class is un-serializable:\n\n```java\n@AutoValue\npublic abstract class Foo implements Serializable {\n\n  public static Foo create(Optional<String> x) {\n    return new AutoValue_Foo(x);\n  }\n\n  // java.util.Optional is not serializable.\n  abstract Optional<String> x;\n}\n```\n\nThis is because `java.util.Optional` is un-serializable. We can make `Foo`\nserializable by using the [`SerializableAutoValueExtension`].\n\n```java\n@SerializableAutoValue  // This annotation activates the extension.\n@AutoValue\npublic abstract class Foo implements Serializable {\n  ...\n}\n```\n\n## Details\n\nFor the example class `Foo` above, `SerializableAutoValueExtension` will\ngenerate the following code:\n\n```java\n@Generated(\"SerializableAutoValueExtension\")\nfinal class AutoValue_Foo extends $AutoValue_Foo {\n\n  // Instead of serializing AutoValue_Foo, we delegate serialization to a\n  // proxy object.\n  Object writeReplace() throws ObjectStreamException {\n    return new Proxy$(this.x);\n  }\n\n  // When serializing, AutoValue_Foo's values are written to Proxy$.\n  // When de-serializing, Proxy$'s values used to create a new instance of\n  // AutoValue_Foo\n  static class Proxy$ implements Serializable {\n\n    private String x;\n\n    // During serialization, un-wrap the Optional field.\n    Proxy$(Optional<String> x) {\n      this.x = x.orElse(null);\n    }\n\n    // During de-serialization, re-create AutoValue_Foo.\n    Object readResolve() throws ObjectStreamException {\n      return new AutoValue_Foo(Optional.ofNullable(x));\n    }\n  }\n}\n```\n\n`SerializableAutoValueExtension` delegates the serialization of `Foo` to a proxy\nobject `Proxy$` where `Foo`'s data is unwrapped.\n\n## Supported Types\n\n`SerializableAutoValueExtension` currently supports the following types:\n\n*   `java.util.Optional`\n*   `com.google.common.collect.ImmutableList`\n    *   Enables `ImmutableList<T>`, where `T` is an un-serializable but\n        supported type, to be serializable.\n*   `com.google.common.collect.ImmutableMap`\n    *   Enables `ImmutableMap<K, V>`, where `K` and/or `V` are un-serializable\n        but supported types, to be serializable.\n\n### Extensions\n\n`SerializableAutoValueExtension` can be extended to support additional\nun-serializable types with [SerializerExtensions].\n\n[`AutoValue`]: https://github.com/google/auto/tree/main/value\n[`SerializableAutoValue`]: https://github.com/google/auto/blob/main/value/src/main/java/com/google/auto/value/extension/serializable/SerializableAutoValue.java\n[`SerializableAutoValueExtension`]: https://github.com/google/auto/blob/main/value/src/main/java/com/google/auto/value/extension/serializable/extension/SerializableAutoValueExtension.java\n[SerializerExtensions]: serializer-extension\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/serializable/g3doc/serializer-extension.md",
    "content": "# Serializer Extensions\n\n\n[`SerializableAutoValueExtension`] can be extended to support additional\nun-serializable types. Extensions are created by implementing\n[`SerializerExtension`].\n\n[TOC]\n\n## Using SerializerExtensions\n\nTo use an extension that's not bundled with [`SerializableAutoValueExtension`],\ninclude it in your `AutoValue` class's dependencies.\n\n## Writing a SerializerExtension\n\nTo add serialization support to a new type, write a class that extends\n[`SerializerExtension`]. Put that class on the `processorpath` along with\n`SerializerExtension`.\n\nSee [`AutoService`] for Java extension loading information.\n\n### How SerializerExtension Works\n\n`SerializableAutoValueExtension` iterates through each property of the\n`@AutoValue` class and tries to look up a `SerializerExtension` for the\nproperty's type. If a `SerializerExtension` is available, a [`Serializer`] is\nreturned. The `Serializer` does three things:\n\n1.  From the original property's type, determine what a suitable serializable\n    type is.\n2.  Generate an expression that maps the original property's value to the proxy\n    value.\n3.  Generate an expression that maps a proxy value back to the original\n    property's value.\n\n### Example\n\nWe have a `Foo` AutoValue class that we would like to serialize:\n\n```java\n@SerializableAutoValue\n@AutoValue\npublic abstract class Foo implements Serializable {\n\n  public static Foo create(Bar bar) {\n    return new AutoValue_Foo(bar);\n  }\n\n  // Bar is unserializable.\n  abstract Bar bar();\n}\n\n// An un-serializable class.\npublic final class Bar {\n\n  public int x;\n\n  public Bar(int x) {\n    this.x = x;\n  }\n}\n```\n\nUnfortunately, `Bar` is un-serializable, which makes the entire class\nun-serializable. We can extend `SerializableAutoValue` to support `Bar` by\nimplementing a `SerializerExtension` for `Bar`.\n\n```java\n// Use AutoService to make BarSerializerExtension discoverable by java.util.ServiceLoader.\n@AutoService(SerializerExtension.class)\npublic final class BarSerializerExtension implements SerializerExtension {\n\n  // Service providers must have a public constructor with no formal parameters.\n  public BarSerializerExtension() {}\n\n  // This method is called for each property in an AutoValue.\n  // When this extension can handle a type (i.e. Bar), we return a Serializer.\n  called on all SerializerExtensions.\n  @Override\n  public Optional<Serializer> getSerializer(\n      TypeMirror type,\n      SerializerFactory factory,\n      ProcessingEnvironment env) {\n    // BarSerializerExtension only handles Bar types.\n    if (!isBar(type)) {\n      return Optional.empty();\n    }\n\n    return Optional.of(new BarSerializer(env));\n  }\n\n  // Our implementation of how Bar should be serialized + de-serialized.\n  private static class BarSerializer implements Serializer {\n\n    private final ProcessingEnvironment env;\n\n    BarSerializer(ProcessingEnvironment env) {\n      this.env = env;\n    }\n\n    // One way to serialize Bar is to just serialize Bar.x.\n    // We can do that by mapping Bar to an int.\n    @Override\n    public TypeMirror proxyFieldType() {\n      return Types.getPrimitiveType(TypeKind.INT);\n    }\n\n    // We need to map Bar to the type we declared in {@link #proxyFieldType}.\n    // Note that {@code expression} is a variable of type Bar.\n    @Override\n    public CodeBlock toProxy(CodeBlock expression) {\n      return CodeBlock.of(\"$L.x\", expression);\n    }\n\n    // We need to map the integer back to a Bar.\n    @Override\n    public CodeBlock fromProxy(CodeBlock expression) {\n      return CodeBlock.of(\"new $T($L)\", Bar.class, expression);\n    }\n  }\n}\n```\n\n`BarSerializerExtension` enables AutoValue classes with `Bar` properties to be\nserialized. For our example class `Foo`, it would help `SerializableAutoValue`\ngenerate the following code:\n\n```java\n@Generated(\"SerializableAutoValueExtension\")\nfinal class AutoValue_Foo extends $AutoValue_Foo {\n\n  Object writeReplace() throws ObjectStreamException {\n    return new Proxy$(this.x);\n  }\n\n  static class Proxy$ implements Serializable {\n\n    // The type is generated by {@code BarSerializer#proxyFieldType}.\n    private int bar;\n\n    Proxy$(Bar bar) {\n      // The assignment expression is generated by {@code BarSerializer#toProxy}.\n      this.bar = bar.x;\n    }\n\n    Object readResolve() throws ObjectStreamException {\n      // The reverse mapping expression is generated by {@code BarSerializer#fromProxy}.\n      return new AutoValue_Foo(new Bar(bar));\n    }\n  }\n}\n```\n\n### Type Parameters\n\nObjects with type parameters are also supported by `SerializerExtension`.\n\nFor example:\n\n```java\n// A potentially un-serializable class, depending on the actual type of T.\npublic final class Baz<T> implements Serializable {\n\n  public T x;\n\n  public Baz(int x) {\n    this.x = x;\n  }\n}\n```\n\n`Baz`'s type argument `T` may not be serializable, but we could create a\n`SerializerExtension` that supports `Baz` by asking for a `SerializerExtension`\nfor `T`.\n\n```java\n@AutoService(SerializerExtension.class)\npublic final class BazSerializerExtension implements SerializerExtension {\n\n  public BazSerializerExtension() {}\n\n  @Override\n  public Optional<Serializer> getSerializer(\n        TypeMirror type,\n        SerializerFactory factory,\n        ProcessingEnvironment env) {\n    if (!isBaz(type)) {\n      return Optional.empty();\n    }\n\n    // Extract the T of Baz<T>.\n    TypeMirror containedType = getContainedType(type);\n\n    // Look up a serializer for the contained type T.\n    Serializer containedTypeSerializer = factory.getSerializer(containedType);\n\n    // If the serializer for the contained type T is an identity function, it\n    // means the contained type is either serializable or unsupported.\n    // Either way, nothing needs to be done. Baz can be serialized as is.\n    if (containedTypeSerializer.isIdentity()) {\n      return Optional.empty();\n    }\n\n    // Make Baz serializable by using the contained type T serializer.\n    return Optional.of(new BazSerializer(containedTypeSerializer));\n  }\n\n  private static class BazSerializer implements Serializer {\n\n    private Serializer serializer;\n\n    BazSerializer(Serializer serialize) {\n      this.serializer = serializer;\n    }\n\n    @Override\n    public TypeMirror proxyFieldType() {\n      // Since the contained type \"T\" is Baz's only field, we map Baz to \"T\"'s\n      // proxy type.\n      return serializer.proxyFieldType();\n    }\n\n    @Override\n    public CodeBlock toProxy(CodeBlock expression) {\n      return serializer.toProxy(expression);\n    }\n\n    @Override\n    public CodeBlock fromProxy(CodeBlock expression) {\n      return serializer.fromProxy(expression);\n    }\n  }\n}\n```\n\nThis implementation uses `SerializerFactory` to find a `Serializer` for `T`. If\na `Serializer` is available, we use it to map `Baz` to a serializable type. If\nno `Serializer` is available, we can do nothing and let `Baz` be serialized\nas-is.\n\n[AutoService]: https://github.com/google/auto/tree/main/service\n[`SerializableAutoValueExtension`]: https://github.com/google/auto/blob/main/value/src/main/java/com/google/auto/value/extension/serializable/extension/SerializableAutoValueExtension.java\n[`SerializerExtension`]: https://github.com/google/auto/blob/main/value/src/main/java/com/google/auto/value/extension/serializable/serializer/interfaces/SerializerExtension.java\n[`Serializer`]: https://github.com/google/auto/blob/main/value/src/main/java/com/google/auto/value/extension/serializable/serializer/interfaces/Serializer.java\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/serializable/processor/ClassNames.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.processor;\n\n/** Names of classes that are referenced in /processor. */\nfinal class ClassNames {\n  static final String SERIALIZABLE_AUTO_VALUE_NAME =\n      \"com.google.auto.value.extension.serializable.SerializableAutoValue\";\n\n  private ClassNames() {}\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/serializable/processor/PropertyMirror.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.processor;\n\nimport javax.lang.model.type.TypeMirror;\n\n/**\n * A POJO containing information about an AutoValue's property.\n *\n * <p>For example, given this AutoValue property: <code>abstract T getX();</code>\n *\n * <ol>\n *   <li>The type would be T.\n *   <li>The name would be x.\n *   <li>The method would be getX.\n */\nfinal class PropertyMirror {\n\n  private final TypeMirror type;\n  private final String name;\n  private final String method;\n\n  PropertyMirror(TypeMirror type, String name, String method) {\n    this.type = type;\n    this.name = name;\n    this.method = method;\n  }\n\n  /** Gets the AutoValue property's type. */\n  TypeMirror getType() {\n    return type;\n  }\n\n  /** Gets the AutoValue property's name. */\n  String getName() {\n    return name;\n  }\n\n  /** Gets the AutoValue property accessor method. */\n  String getMethod() {\n    return method;\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/serializable/processor/SerializableAutoValueExtension.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.processor;\n\nimport static com.google.auto.value.extension.serializable.processor.ClassNames.SERIALIZABLE_AUTO_VALUE_NAME;\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static com.google.common.collect.ImmutableMap.toImmutableMap;\nimport static java.util.stream.Collectors.joining;\n\nimport com.google.auto.common.GeneratedAnnotationSpecs;\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.service.AutoService;\nimport com.google.auto.value.extension.AutoValueExtension;\nimport com.google.auto.value.extension.serializable.serializer.SerializerFactoryLoader;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.SerializerFactory;\nimport com.google.common.base.Equivalence;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.squareup.javapoet.AnnotationSpec;\nimport com.squareup.javapoet.ClassName;\nimport com.squareup.javapoet.CodeBlock;\nimport com.squareup.javapoet.FieldSpec;\nimport com.squareup.javapoet.JavaFile;\nimport com.squareup.javapoet.MethodSpec;\nimport com.squareup.javapoet.ParameterizedTypeName;\nimport com.squareup.javapoet.TypeName;\nimport com.squareup.javapoet.TypeSpec;\nimport com.squareup.javapoet.TypeVariableName;\nimport java.io.Serializable;\nimport java.util.List;\nimport java.util.Optional;\nimport java.util.function.Function;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.Modifier;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.TypeMirror;\n\n/**\n * An AutoValue extension that enables classes with unserializable fields to be serializable.\n *\n * <p>For this extension to work:\n *\n * <ul>\n *   <li>The AutoValue class must implement {@link Serializable}.\n *   <li>Unserializable fields in the AutoValue class must be supported by a {@link\n *       com.google.auto.value.extension.serializable.serializer.interfaces.SerializerExtension}.\n * </ul>\n */\n@AutoService(AutoValueExtension.class)\npublic final class SerializableAutoValueExtension extends AutoValueExtension {\n\n  @Override\n  public boolean applicable(Context context) {\n    return hasSerializableInterface(context) && hasSerializableAutoValueAnnotation(context);\n  }\n\n  @Override\n  public IncrementalExtensionType incrementalType(ProcessingEnvironment processingEnvironment) {\n    return IncrementalExtensionType.ISOLATING;\n  }\n\n  @Override\n  public String generateClass(\n      Context context, String className, String classToExtend, boolean isFinal) {\n    return new Generator(context, className, classToExtend, isFinal).generate();\n  }\n\n  private static final class Generator {\n    private final Context context;\n    private final String className;\n    private final String classToExtend;\n    private final boolean isFinal;\n    private final ImmutableList<PropertyMirror> propertyMirrors;\n    private final ImmutableList<TypeVariableName> typeVariableNames;\n    private final ProxyGenerator proxyGenerator;\n\n    Generator(Context context, String className, String classToExtend, boolean isFinal) {\n      this.context = context;\n      this.className = className;\n      this.classToExtend = classToExtend;\n      this.isFinal = isFinal;\n\n      this.propertyMirrors =\n          context.propertyTypes().entrySet().stream()\n              .map(\n                  entry ->\n                      new PropertyMirror(\n                          /* type= */ entry.getValue(),\n                          /* name= */ entry.getKey(),\n                          /* method= */ context\n                              .properties()\n                              .get(entry.getKey())\n                              .getSimpleName()\n                              .toString()))\n              .collect(toImmutableList());\n      this.typeVariableNames =\n          context.autoValueClass().getTypeParameters().stream()\n              .map(TypeVariableName::get)\n              .collect(toImmutableList());\n\n      TypeName classTypeName =\n          getClassTypeName(\n              ClassName.get(context.packageName(), context.finalAutoValueClassName()),\n              typeVariableNames);\n      this.proxyGenerator =\n          new ProxyGenerator(\n              classTypeName, typeVariableNames, propertyMirrors, buildSerializersMap());\n    }\n\n    private String generate() {\n      ClassName superclass = ClassName.get(context.packageName(), classToExtend);\n      Optional<AnnotationSpec> generatedAnnotationSpec =\n          GeneratedAnnotationSpecs.generatedAnnotationSpec(\n              context.processingEnvironment().getElementUtils(),\n              context.processingEnvironment().getSourceVersion(),\n              SerializableAutoValueExtension.class);\n\n      TypeSpec.Builder subclass =\n          TypeSpec.classBuilder(className)\n              .superclass(getClassTypeName(superclass, typeVariableNames))\n              .addTypeVariables(typeVariableNames)\n              .addModifiers(isFinal ? Modifier.FINAL : Modifier.ABSTRACT)\n              .addMethod(constructor())\n              .addMethod(writeReplace())\n              .addType(proxyGenerator.generate());\n      generatedAnnotationSpec.ifPresent(subclass::addAnnotation);\n\n      return JavaFile.builder(context.packageName(), subclass.build()).build().toString();\n    }\n\n    /** Creates a constructor that calls super with all the AutoValue fields. */\n    private MethodSpec constructor() {\n      MethodSpec.Builder constructor =\n          MethodSpec.constructorBuilder()\n              .addStatement(\n                  \"super($L)\",\n                  propertyMirrors.stream().map(PropertyMirror::getName).collect(joining(\", \")));\n\n      for (PropertyMirror propertyMirror : propertyMirrors) {\n        constructor.addParameter(TypeName.get(propertyMirror.getType()), propertyMirror.getName());\n      }\n\n      return constructor.build();\n    }\n\n    /**\n     * Creates an implementation of writeReplace that delegates serialization to its inner Proxy\n     * class.\n     */\n    private MethodSpec writeReplace() {\n      ImmutableList<CodeBlock> properties =\n          propertyMirrors.stream()\n              .map(propertyMirror -> CodeBlock.of(\"$L()\", propertyMirror.getMethod()))\n              .collect(toImmutableList());\n\n      return MethodSpec.methodBuilder(\"writeReplace\")\n          .returns(Object.class)\n          .addStatement(\n              \"return new $T($L)\",\n              getClassTypeName(\n                  ClassName.get(\n                      context.packageName(),\n                      className,\n                      SerializableAutoValueExtension.ProxyGenerator.PROXY_CLASS_NAME),\n                  typeVariableNames),\n              CodeBlock.join(properties, \", \"))\n          .build();\n    }\n\n    private ImmutableMap<Equivalence.Wrapper<TypeMirror>, Serializer> buildSerializersMap() {\n      SerializerFactory factory =\n          SerializerFactoryLoader.getFactory(context.processingEnvironment());\n      return propertyMirrors.stream()\n          .map(PropertyMirror::getType)\n          .map(MoreTypes.equivalence()::wrap)\n          .distinct()\n          .collect(\n              toImmutableMap(\n                  Function.identity(), equivalence -> factory.getSerializer(equivalence.get())));\n    }\n\n    /** Adds type parameters to the given {@link ClassName}, if available. */\n    private static TypeName getClassTypeName(\n        ClassName className, List<TypeVariableName> typeVariableNames) {\n      return typeVariableNames.isEmpty()\n          ? className\n          : ParameterizedTypeName.get(className, typeVariableNames.toArray(new TypeName[] {}));\n    }\n  }\n\n  /** A generator of nested serializable Proxy classes. */\n  private static final class ProxyGenerator {\n    private static final String PROXY_CLASS_NAME = \"Proxy$\";\n\n    private final TypeName outerClassTypeName;\n    private final ImmutableList<TypeVariableName> typeVariableNames;\n    private final ImmutableList<PropertyMirror> propertyMirrors;\n    private final ImmutableMap<Equivalence.Wrapper<TypeMirror>, Serializer> serializersMap;\n\n    ProxyGenerator(\n        TypeName outerClassTypeName,\n        ImmutableList<TypeVariableName> typeVariableNames,\n        ImmutableList<PropertyMirror> propertyMirrors,\n        ImmutableMap<Equivalence.Wrapper<TypeMirror>, Serializer> serializersMap) {\n      this.outerClassTypeName = outerClassTypeName;\n      this.typeVariableNames = typeVariableNames;\n      this.propertyMirrors = propertyMirrors;\n      this.serializersMap = serializersMap;\n    }\n\n    private TypeSpec generate() {\n      TypeSpec.Builder proxy =\n          TypeSpec.classBuilder(PROXY_CLASS_NAME)\n              .addModifiers(Modifier.STATIC)\n              .addTypeVariables(typeVariableNames)\n              .addSuperinterface(Serializable.class)\n              .addField(serialVersionUid())\n              .addFields(properties())\n              .addMethod(constructor())\n              .addMethod(readResolve());\n\n      return proxy.build();\n    }\n\n    private static FieldSpec serialVersionUid() {\n      return FieldSpec.builder(\n              long.class, \"serialVersionUID\", Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)\n          .initializer(\"0\")\n          .build();\n    }\n\n    /** Maps each AutoValue property to a serializable type. */\n    private List<FieldSpec> properties() {\n      return propertyMirrors.stream()\n          .map(\n              propertyMirror ->\n                  FieldSpec.builder(\n                          TypeName.get(\n                              serializersMap\n                                  .get(MoreTypes.equivalence().wrap(propertyMirror.getType()))\n                                  .proxyFieldType()),\n                          propertyMirror.getName(),\n                          Modifier.PRIVATE)\n                      .build())\n          .collect(toImmutableList());\n    }\n\n    /** Creates a constructor that converts the AutoValue's properties to serializable values. */\n    private MethodSpec constructor() {\n      MethodSpec.Builder constructor = MethodSpec.constructorBuilder();\n\n      for (PropertyMirror propertyMirror : propertyMirrors) {\n        Serializer serializer =\n            serializersMap.get(MoreTypes.equivalence().wrap(propertyMirror.getType()));\n        String name = propertyMirror.getName();\n\n        constructor.addParameter(TypeName.get(propertyMirror.getType()), name);\n        constructor.addStatement(\n            CodeBlock.of(\"this.$L = $L\", name, serializer.toProxy(CodeBlock.of(name))));\n      }\n\n      return constructor.build();\n    }\n\n    /**\n     * Creates an implementation of {@code readResolve} that returns the serializable values in the\n     * Proxy object back to their original types.\n     */\n    private MethodSpec readResolve() {\n      return MethodSpec.methodBuilder(\"readResolve\")\n          .returns(Object.class)\n          .addException(Exception.class)\n          .addStatement(\n              \"return new $T($L)\",\n              outerClassTypeName,\n              CodeBlock.join(\n                  propertyMirrors.stream().map(this::resolve).collect(toImmutableList()), \", \"))\n          .build();\n    }\n\n    /** Maps a serializable type back to its original AutoValue property. */\n    private CodeBlock resolve(PropertyMirror propertyMirror) {\n      return serializersMap\n          .get(MoreTypes.equivalence().wrap(propertyMirror.getType()))\n          .fromProxy(CodeBlock.of(propertyMirror.getName()));\n    }\n  }\n\n  private static boolean hasSerializableInterface(Context context) {\n    final TypeMirror serializableTypeMirror =\n        context\n            .processingEnvironment()\n            .getElementUtils()\n            .getTypeElement(Serializable.class.getCanonicalName())\n            .asType();\n\n    return context\n        .processingEnvironment()\n        .getTypeUtils()\n        .isAssignable(context.autoValueClass().asType(), serializableTypeMirror);\n  }\n\n  private static boolean hasSerializableAutoValueAnnotation(Context context) {\n    return context.autoValueClass().getAnnotationMirrors().stream()\n        .map(AnnotationMirror::getAnnotationType)\n        .map(MoreTypes::asTypeElement)\n        .map(TypeElement::getQualifiedName)\n        .anyMatch(name -> name.contentEquals(SERIALIZABLE_AUTO_VALUE_NAME));\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/serializable/serializer/SerializerFactoryLoader.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.serializer;\n\nimport com.google.auto.value.extension.serializable.serializer.impl.SerializerFactoryImpl;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.SerializerExtension;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.SerializerFactory;\nimport com.google.auto.value.processor.SimpleServiceLoader;\nimport com.google.common.base.Throwables;\nimport com.google.common.collect.ImmutableList;\nimport java.util.Optional;\nimport java.util.regex.Pattern;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.tools.Diagnostic;\n\n/**\n * Builds a {@link SerializerFactory} populated with discovered {@link SerializerExtension}\n * instances.\n */\npublic final class SerializerFactoryLoader {\n\n  /**\n   * Returns a {@link SerializerFactory} with {@link SerializerExtension} instances provided by the\n   * {@link java.util.ServiceLoader}.\n   */\n  public static SerializerFactory getFactory(ProcessingEnvironment processingEnv) {\n    return new SerializerFactoryImpl(loadExtensions(processingEnv), processingEnv);\n  }\n\n  private static ImmutableList<SerializerExtension> loadExtensions(\n      ProcessingEnvironment processingEnv) {\n    // The below is a workaround for a test-building bug. We don't expect to support it indefinitely\n    // so don't depend on it.\n    String allowedMissingClasses =\n        processingEnv.getOptions().get(\"allowedMissingSerializableExtensionClasses\");\n    Optional<Pattern> allowedMissingClassesPattern =\n        Optional.ofNullable(allowedMissingClasses).map(Pattern::compile);\n    try {\n      return ImmutableList.copyOf(\n          SimpleServiceLoader.load(\n              SerializerExtension.class,\n              SerializerFactoryLoader.class.getClassLoader(),\n              allowedMissingClassesPattern));\n    } catch (Throwable t) {\n      processingEnv\n          .getMessager()\n          .printMessage(\n              Diagnostic.Kind.ERROR,\n              \"An exception occurred while looking for SerializerExtensions. No extensions will\"\n                  + \" function.\\n\"\n                  + Throwables.getStackTraceAsString(t));\n      return ImmutableList.of();\n    }\n  }\n\n  private SerializerFactoryLoader() {}\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/IdentitySerializerFactory.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.serializer.impl;\n\nimport com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;\nimport com.squareup.javapoet.CodeBlock;\nimport javax.lang.model.type.TypeMirror;\n\n/** Creates identity {@link Serializer} instances. */\npublic final class IdentitySerializerFactory {\n\n  /** Returns a {@link Serializer} that leaves the type as is. */\n  public static Serializer getSerializer(TypeMirror typeMirror) {\n    return new IdentitySerializer(typeMirror);\n  }\n\n  private static class IdentitySerializer implements Serializer {\n\n    private final TypeMirror typeMirror;\n\n    IdentitySerializer(TypeMirror typeMirror) {\n      this.typeMirror = typeMirror;\n    }\n\n    @Override\n    public TypeMirror proxyFieldType() {\n      return typeMirror;\n    }\n\n    @Override\n    public CodeBlock toProxy(CodeBlock expression) {\n      return expression;\n    }\n\n    @Override\n    public CodeBlock fromProxy(CodeBlock expression) {\n      return expression;\n    }\n\n    @Override\n    public boolean isIdentity() {\n      return true;\n    }\n  }\n\n  private IdentitySerializerFactory() {}\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/ImmutableListSerializerExtension.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.serializer.impl;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.service.AutoService;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.SerializerExtension;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.SerializerFactory;\nimport com.google.auto.value.extension.serializable.serializer.runtime.FunctionWithExceptions;\nimport com.google.common.collect.ImmutableList;\nimport com.squareup.javapoet.CodeBlock;\nimport java.util.Optional;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\n\n/**\n * A {@link SerializerExtension} that deserializes objects inside an {@link ImmutableList}.\n *\n * <p>Enables unserializable objects inside an ImmutableList to be serializable.\n */\n@AutoService(SerializerExtension.class)\npublic final class ImmutableListSerializerExtension implements SerializerExtension {\n\n  public ImmutableListSerializerExtension() {}\n\n  @Override\n  public Optional<Serializer> getSerializer(\n      TypeMirror typeMirror, SerializerFactory factory, ProcessingEnvironment processingEnv) {\n    if (!isImmutableList(typeMirror)) {\n      return Optional.empty();\n    }\n\n    // Extract the T of ImmutableList<T>.\n    TypeMirror containedType = getContainedType(typeMirror);\n    Serializer containedTypeSerializer = factory.getSerializer(containedType);\n\n    // We don't need this serializer if the T of ImmutableList<T> is serializable.\n    if (containedTypeSerializer.isIdentity()) {\n      return Optional.empty();\n    }\n\n    return Optional.of(\n        new ImmutableListSerializer(containedTypeSerializer, factory, processingEnv));\n  }\n\n  private static class ImmutableListSerializer implements Serializer {\n\n    private final Serializer containedTypeSerializer;\n    private final SerializerFactory factory;\n    private final ProcessingEnvironment processingEnv;\n\n    ImmutableListSerializer(\n        Serializer containedTypeSerializer,\n        SerializerFactory factory,\n        ProcessingEnvironment processingEnv) {\n      this.containedTypeSerializer = containedTypeSerializer;\n      this.factory = factory;\n      this.processingEnv = processingEnv;\n    }\n\n    @Override\n    public TypeMirror proxyFieldType() {\n      TypeElement immutableListTypeElement =\n          processingEnv.getElementUtils().getTypeElement(ImmutableList.class.getCanonicalName());\n      TypeMirror containedProxyType = containedTypeSerializer.proxyFieldType();\n      return processingEnv\n          .getTypeUtils()\n          .getDeclaredType(immutableListTypeElement, containedProxyType);\n    }\n\n    @Override\n    public CodeBlock toProxy(CodeBlock expression) {\n      CodeBlock element = factory.newIdentifier(\"value\");\n      return CodeBlock.of(\n          \"$L.stream().map($T.wrapper($L -> $L)).collect($T.toImmutableList())\",\n          expression,\n          FunctionWithExceptions.class,\n          element,\n          containedTypeSerializer.toProxy(element),\n          ImmutableList.class);\n    }\n\n    @Override\n    public CodeBlock fromProxy(CodeBlock expression) {\n      CodeBlock element = factory.newIdentifier(\"value\");\n      return CodeBlock.of(\n          \"$L.stream().map($T.wrapper($L -> $L)).collect($T.toImmutableList())\",\n          expression,\n          FunctionWithExceptions.class,\n          element,\n          containedTypeSerializer.fromProxy(element),\n          ImmutableList.class);\n    }\n  }\n\n  private static boolean isImmutableList(TypeMirror type) {\n    if (type.getKind() != TypeKind.DECLARED) {\n      return false;\n    }\n\n    return MoreTypes.asTypeElement(type)\n        .getQualifiedName()\n        .contentEquals(\"com.google.common.collect.ImmutableList\");\n  }\n\n  private static TypeMirror getContainedType(TypeMirror type) {\n    return MoreTypes.asDeclared(type).getTypeArguments().get(0);\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/ImmutableMapSerializerExtension.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.serializer.impl;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.service.AutoService;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.SerializerExtension;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.SerializerFactory;\nimport com.google.auto.value.extension.serializable.serializer.runtime.FunctionWithExceptions;\nimport com.google.common.collect.ImmutableMap;\nimport com.squareup.javapoet.CodeBlock;\nimport java.util.Optional;\nimport java.util.function.Function;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\n\n/**\n * A {@link SerializerExtension} that deserializes objects inside an {@link ImmutableMap}.\n *\n * <p>Enables unserializable objects inside an ImmutableMap to be serializable.\n */\n@AutoService(SerializerExtension.class)\npublic final class ImmutableMapSerializerExtension implements SerializerExtension {\n\n  public ImmutableMapSerializerExtension() {}\n\n  @Override\n  public Optional<Serializer> getSerializer(\n      TypeMirror typeMirror, SerializerFactory factory, ProcessingEnvironment processingEnv) {\n    if (!isImmutableMap(typeMirror)) {\n      return Optional.empty();\n    }\n\n    // Extract the K, V of ImmutableMap<K, V>.\n    TypeMirror keyType = getKeyType(typeMirror);\n    TypeMirror valueType = getValueType(typeMirror);\n    Serializer keyTypeSerializer = factory.getSerializer(keyType);\n    Serializer valueTypeSerializer = factory.getSerializer(valueType);\n\n    // We don't need this serializer if the K and V of ImmutableMap<K, V> are serializable.\n    if (keyTypeSerializer.isIdentity() && valueTypeSerializer.isIdentity()) {\n      return Optional.empty();\n    }\n\n    return Optional.of(\n        new ImmutableMapSerializer(\n            keyType, valueType, keyTypeSerializer, valueTypeSerializer, factory, processingEnv));\n  }\n\n  private static class ImmutableMapSerializer implements Serializer {\n\n    private final TypeMirror keyType;\n    private final TypeMirror valueType;\n    private final TypeMirror keyProxyType;\n    private final TypeMirror valueProxyType;\n    private final Serializer keyTypeSerializer;\n    private final Serializer valueTypeSerializer;\n    private final SerializerFactory factory;\n    private final ProcessingEnvironment processingEnv;\n\n    ImmutableMapSerializer(\n        TypeMirror keyType,\n        TypeMirror valueType,\n        Serializer keyTypeSerializer,\n        Serializer valueTypeSerializer,\n        SerializerFactory factory,\n        ProcessingEnvironment processingEnv) {\n      this.keyType = keyType;\n      this.valueType = valueType;\n      this.keyProxyType = keyTypeSerializer.proxyFieldType();\n      this.valueProxyType = valueTypeSerializer.proxyFieldType();\n      this.keyTypeSerializer = keyTypeSerializer;\n      this.valueTypeSerializer = valueTypeSerializer;\n      this.factory = factory;\n      this.processingEnv = processingEnv;\n    }\n\n    @Override\n    public TypeMirror proxyFieldType() {\n      TypeElement immutableMapTypeElement =\n          processingEnv.getElementUtils().getTypeElement(ImmutableMap.class.getCanonicalName());\n      return processingEnv\n          .getTypeUtils()\n          .getDeclaredType(immutableMapTypeElement, keyProxyType, valueProxyType);\n    }\n\n    @Override\n    public CodeBlock toProxy(CodeBlock expression) {\n      return CodeBlock.of(\n          \"$L.entrySet().stream().collect($T.toImmutableMap($L, $L))\",\n          expression,\n          ImmutableMap.class,\n          generateKeyMapFunction(keyType, keyProxyType, keyTypeSerializer::toProxy),\n          generateValueMapFunction(valueType, valueProxyType, valueTypeSerializer::toProxy));\n    }\n\n    @Override\n    public CodeBlock fromProxy(CodeBlock expression) {\n      return CodeBlock.of(\n          \"$L.entrySet().stream().collect($T.toImmutableMap($L, $L))\",\n          expression,\n          ImmutableMap.class,\n          generateKeyMapFunction(keyProxyType, keyType, keyTypeSerializer::fromProxy),\n          generateValueMapFunction(valueProxyType, valueType, valueTypeSerializer::fromProxy));\n    }\n\n    private CodeBlock generateKeyMapFunction(\n        TypeMirror originalType,\n        TypeMirror transformedType,\n        Function<CodeBlock, CodeBlock> proxyMap) {\n      CodeBlock element = factory.newIdentifier(\"element\");\n      CodeBlock value = factory.newIdentifier(\"value\");\n      return CodeBlock.of(\n          \"$1L -> $2T.<$3T, $4T>wrapper($5L -> $6L).apply($1L.getKey())\",\n          value,\n          FunctionWithExceptions.class,\n          originalType,\n          transformedType,\n          element,\n          proxyMap.apply(element));\n    }\n\n    private CodeBlock generateValueMapFunction(\n        TypeMirror originalType,\n        TypeMirror transformedType,\n        Function<CodeBlock, CodeBlock> proxyMap) {\n      CodeBlock element = factory.newIdentifier(\"element\");\n      CodeBlock value = factory.newIdentifier(\"value\");\n      return CodeBlock.of(\n          \"$1L -> $2T.<$3T, $4T>wrapper($5L -> $6L).apply($1L.getValue())\",\n          value,\n          FunctionWithExceptions.class,\n          originalType,\n          transformedType,\n          element,\n          proxyMap.apply(element));\n    }\n  }\n\n  private static boolean isImmutableMap(TypeMirror type) {\n    if (type.getKind() != TypeKind.DECLARED) {\n      return false;\n    }\n\n    return MoreTypes.asTypeElement(type)\n        .getQualifiedName()\n        .contentEquals(\"com.google.common.collect.ImmutableMap\");\n  }\n\n  private static TypeMirror getKeyType(TypeMirror type) {\n    return MoreTypes.asDeclared(type).getTypeArguments().get(0);\n  }\n\n  private static TypeMirror getValueType(TypeMirror type) {\n    return MoreTypes.asDeclared(type).getTypeArguments().get(1);\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/OptionalSerializerExtension.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.serializer.impl;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.service.AutoService;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.SerializerExtension;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.SerializerFactory;\nimport com.squareup.javapoet.CodeBlock;\nimport java.util.Optional;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\n\n/**\n * A {@link SerializerExtension} that enables {@link Optional} types to be serialized.\n *\n * <p>The type argument {@code T} of {@code Optional<T>} is queried against the {@link\n * SerializerFactory}.\n */\n@AutoService(SerializerExtension.class)\npublic final class OptionalSerializerExtension implements SerializerExtension {\n\n  public OptionalSerializerExtension() {}\n\n  /** Creates a {@link Serializer} that supports {@link Optional} types. */\n  @Override\n  public Optional<Serializer> getSerializer(\n      TypeMirror typeMirror, SerializerFactory factory, ProcessingEnvironment processingEnv) {\n    if (!isOptional(typeMirror)) {\n      return Optional.empty();\n    }\n\n    // Extract the T of Optional<T>.\n    TypeMirror containedType = getContainedType(typeMirror);\n    Serializer containedTypeSerializer = factory.getSerializer(containedType);\n\n    return Optional.of(new OptionalSerializer(containedTypeSerializer));\n  }\n\n  private static class OptionalSerializer implements Serializer {\n\n    private final Serializer containedTypeSerializer;\n\n    OptionalSerializer(Serializer containedTypeSerializer) {\n      this.containedTypeSerializer = containedTypeSerializer;\n    }\n\n    @Override\n    public TypeMirror proxyFieldType() {\n      // If this is an Optional<String> then the proxy field type is String.\n      // If this is an Optional<Foo>, and the proxy field type for Foo is Bar, then the proxy field\n      // type for Optional<Foo> is Bar.\n      return containedTypeSerializer.proxyFieldType();\n    }\n\n    @Override\n    public CodeBlock toProxy(CodeBlock expression) {\n      return CodeBlock.of(\n          \"$L.isPresent() ? $L : null\",\n          expression,\n          containedTypeSerializer.toProxy(CodeBlock.of(\"$L.get()\", expression)));\n    }\n\n    @Override\n    public CodeBlock fromProxy(CodeBlock expression) {\n      return CodeBlock.of(\n          \"$T.ofNullable($L == null ? null : $L)\",\n          Optional.class,\n          expression,\n          containedTypeSerializer.fromProxy(expression));\n    }\n  }\n\n  /** Checks if the given type is an {@link Optional}. */\n  private static boolean isOptional(TypeMirror type) {\n    if (type.getKind() != TypeKind.DECLARED) {\n      return false;\n    }\n\n    return MoreTypes.asTypeElement(type).getQualifiedName().contentEquals(\"java.util.Optional\");\n  }\n\n  /**\n   * Gets the given type's first type argument.\n   *\n   * <p>Returns the {@code T} in {@code Optional<T>}.\n   */\n  private static TypeMirror getContainedType(TypeMirror type) {\n    return MoreTypes.asDeclared(type).getTypeArguments().get(0);\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/SerializerFactoryImpl.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.serializer.impl;\n\nimport com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.SerializerExtension;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.SerializerFactory;\nimport com.google.common.collect.ImmutableList;\nimport com.squareup.javapoet.CodeBlock;\nimport java.util.Optional;\nimport java.util.concurrent.atomic.AtomicInteger;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.type.TypeMirror;\n\n/** A concrete implementation of {@link SerializerFactory}. */\npublic final class SerializerFactoryImpl implements SerializerFactory {\n\n  private final ImmutableList<SerializerExtension> extensions;\n  private final ProcessingEnvironment env;\n  private final AtomicInteger idCount = new AtomicInteger();\n\n  public SerializerFactoryImpl(\n      ImmutableList<SerializerExtension> extensions, ProcessingEnvironment env) {\n    this.extensions = extensions;\n    this.env = env;\n  }\n\n  @Override\n  public Serializer getSerializer(TypeMirror typeMirror) {\n    for (SerializerExtension extension : extensions) {\n      Optional<Serializer> serializer = extension.getSerializer(typeMirror, this, env);\n      if (serializer.isPresent()) {\n        return serializer.get();\n      }\n    }\n    return IdentitySerializerFactory.getSerializer(typeMirror);\n  }\n\n  @Override\n  public CodeBlock newIdentifier(String prefix) {\n    return CodeBlock.of(\"$L$$$L\", prefix, idCount.incrementAndGet());\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/serializable/serializer/interfaces/Serializer.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.serializer.interfaces;\n\nimport com.squareup.javapoet.CodeBlock;\nimport javax.lang.model.type.TypeMirror;\n\n/**\n * A Serializer, at compile time, generates code to map an unserializable type to a serializable\n * type. It also generates the reverse code to re-create the original type.\n */\npublic interface Serializer {\n\n  /** The proxy type the original unserializable type will be mapped to. */\n  TypeMirror proxyFieldType();\n\n  /** Creates an expression that converts the original type to the proxy type. */\n  CodeBlock toProxy(CodeBlock expression);\n\n  /** Creates an expression that converts the proxy type back to the original type. */\n  CodeBlock fromProxy(CodeBlock expression);\n\n  /** Returns true if this is an identity {@link Serializer}. */\n  default boolean isIdentity() {\n    return false;\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/serializable/serializer/interfaces/SerializerExtension.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.serializer.interfaces;\n\nimport java.util.Optional;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.type.TypeMirror;\n\n/**\n * A SerializerExtension allows unserializable types to be serialized by SerializableAutoValue.\n *\n * <p>Extensions are discovered at compile time using the {@link java.util.ServiceLoader} APIs,\n * allowing them to run without any additional annotations. To be found by {@code ServiceLoader}, an\n * extension class must be public with a public no-arg constructor, and its fully-qualified name\n * must appear in a file called {@code\n * META-INF/services/com.google.auto.value.extension.serializable.serializer.interfaces.SerializerExtension}\n * in a jar that is on the compiler's {@code -classpath} or {@code -processorpath}.\n *\n * <p>When SerializableAutoValue maps each field in an AutoValue to a serializable proxy object, it\n * asks each SerializerExtension whether it can generate code to make the given type serializable. A\n * SerializerExtension replies that it can by returning a non-empty {@link Serializer}.\n *\n * <p>A SerializerExtension is also provided with a SerializerFactory, which it can use to query\n * nested types.\n */\npublic interface SerializerExtension {\n\n  /**\n   * Returns a {@link Serializer} if this {@link SerializerExtension} applies to the given {@code\n   * type}. Otherwise, {@code Optional.empty} is returned.\n   *\n   * @param type the type being serialized\n   * @param factory a {@link SerializerFactory} that can be used to serialize nested types\n   * @param processingEnv the processing environment provided by the annotation processing framework\n   */\n  Optional<Serializer> getSerializer(\n      TypeMirror type, SerializerFactory factory, ProcessingEnvironment processingEnv);\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/serializable/serializer/interfaces/SerializerFactory.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.serializer.interfaces;\n\nimport com.squareup.javapoet.CodeBlock;\nimport javax.lang.model.type.TypeMirror;\n\n/**\n * A factory that returns a {@link Serializer} for any given {@link TypeMirror}.\n *\n * <p>Defaults to an identity serializer if no SerializerExtensions are suitable.\n */\npublic interface SerializerFactory {\n\n  /** Returns a {@link Serializer} for the given {@link TypeMirror}. */\n  Serializer getSerializer(TypeMirror type);\n\n  /**\n   * Returns an identifier beginning with the given prefix and that is distinct from any identifier\n   * returned by another call to this method. The returned identifier will contain a {@code $},\n   * which should also mean it is distinct from identifiers in user code that are in scope.\n   *\n   * <p>The default implementation of this method throws {@link UnsupportedOperationException} for\n   * compatibility reasons.\n   */\n  default CodeBlock newIdentifier(String prefix) {\n    throw new UnsupportedOperationException();\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/serializable/serializer/runtime/FunctionWithExceptions.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.serializer.runtime;\n\nimport java.util.function.Function;\n\n/** A utility for lambdas that throw exceptions. */\npublic final class FunctionWithExceptions {\n\n  /** Creates a wrapper for lambdas that converts checked exceptions to runtime exceptions. */\n  public static <I, O> Function<I, O> wrapper(FunctionWithException<I, O> fe) {\n    return arg -> {\n      try {\n        return fe.apply(arg);\n      } catch (Exception e) {\n        throw new RuntimeException(e);\n      }\n    };\n  }\n\n  /** A function that can throw an exception. */\n  @FunctionalInterface\n  public interface FunctionWithException<I, O> {\n    O apply(I i) throws Exception;\n  }\n\n  private FunctionWithExceptions() {}\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/toprettystring/ToPrettyString.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.auto.value.extension.toprettystring;\n\nimport static java.lang.annotation.ElementType.METHOD;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.Target;\nimport java.util.Collection;\n\n/**\n * Annotates instance methods that return an easy-to-read {@link String} representing the instance.\n * When the method is {@code abstract} and enclosed in an {@link com.google.auto.value.AutoValue}\n * class, an implementation of the method will be automatically generated.\n *\n * <p>When generating an implementation of an {@code @ToPrettyString} method, each property of the\n * {@code @AutoValue} type is individually printed in an easy-to-read format. If the type of the\n * property itself has a {@code @ToPrettyString} method, that method will be called in assistance of\n * computing the pretty string. Non-{@code @AutoValue} classes can contribute a pretty string\n * representation by annotating a method with {@code @ToPrettyString}.\n *\n * <p>{@link Collection} and {@link Collection}-like types have special representations in generated\n * pretty strings.\n *\n * <p>If no {@code @ToPrettyString} method is found on a type and the type is not one with a built\n * in rendering, the {@link Object#toString()} value will be used instead.\n *\n * <p>{@code @ToPrettyString} is valid on overridden {@code toString()} and other methods alike.\n *\n * <h2>Example</h2>\n *\n * <pre>{@code\n * @AutoValue\n * abstract class Pretty {\n *   abstract List<String> property();\n *\n *   @ToPrettyString\n *   abstract String toPrettyString();\n * }\n *\n * System.out.println(new AutoValue_Pretty(List.of(\"abc\", \"def\", \"has\\nnewline\")).toPrettyString())\n * // Pretty{\n * //   property = [\n * //     abc,\n * //     def,\n * //     has\n * //     newline,\n * //   ]\n * // }\n * }</pre>\n */\n@Documented\n@Target(METHOD)\npublic @interface ToPrettyString {}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/toprettystring/processor/Annotations.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.auto.value.extension.toprettystring.processor;\n\nimport static com.google.auto.value.extension.toprettystring.processor.ClassNames.TO_PRETTY_STRING_NAME;\n\nimport com.google.auto.common.MoreTypes;\nimport java.util.Optional;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.TypeElement;\n\n/** Extension methods for working with {@link AnnotationMirror}. */\nfinal class Annotations {\n  static Optional<AnnotationMirror> getAnnotationMirror(Element element, String annotationName) {\n    for (AnnotationMirror annotation : element.getAnnotationMirrors()) {\n      TypeElement annotationElement = MoreTypes.asTypeElement(annotation.getAnnotationType());\n      if (annotationElement.getQualifiedName().contentEquals(annotationName)) {\n        return Optional.of(annotation);\n      }\n    }\n    return Optional.empty();\n  }\n\n  static Optional<AnnotationMirror> toPrettyStringAnnotation(Element element) {\n    return getAnnotationMirror(element, TO_PRETTY_STRING_NAME);\n  }\n\n  private Annotations() {}\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/toprettystring/processor/ClassNames.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.auto.value.extension.toprettystring.processor;\n\n/** Names of classes that are referenced in the processor/extension. */\nfinal class ClassNames {\n  static final String TO_PRETTY_STRING_NAME =\n      \"com.google.auto.value.extension.toprettystring.ToPrettyString\";\n\n  private ClassNames() {}\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/toprettystring/processor/ExtensionClassTypeSpecBuilder.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.auto.value.extension.toprettystring.processor;\n\nimport static com.google.auto.common.GeneratedAnnotationSpecs.generatedAnnotationSpec;\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static com.google.common.collect.ImmutableMap.toImmutableMap;\nimport static com.squareup.javapoet.MethodSpec.constructorBuilder;\nimport static com.squareup.javapoet.TypeSpec.classBuilder;\nimport static java.util.stream.Collectors.joining;\nimport static java.util.stream.Collectors.toList;\nimport static javax.lang.model.element.Modifier.ABSTRACT;\nimport static javax.lang.model.element.Modifier.FINAL;\n\nimport com.google.auto.value.extension.AutoValueExtension;\nimport com.google.auto.value.extension.AutoValueExtension.Context;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.squareup.javapoet.AnnotationSpec;\nimport com.squareup.javapoet.ClassName;\nimport com.squareup.javapoet.MethodSpec;\nimport com.squareup.javapoet.ParameterizedTypeName;\nimport com.squareup.javapoet.TypeName;\nimport com.squareup.javapoet.TypeSpec;\nimport com.squareup.javapoet.TypeVariableName;\nimport java.util.List;\nimport java.util.Set;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.Elements;\n\n/**\n * A factory for {@link TypeSpec}s used in {@link AutoValueExtension} implementations.\n *\n * <p>This is copied from {@link\n * com.google.auto.value.extension.memoized.processor.MemoizeExtension} until we find a better\n * location to consolidate the code.\n */\nfinal class ExtensionClassTypeSpecBuilder {\n\n  private final Context context;\n  private final String className;\n  private final String classToExtend;\n  private final boolean isFinal;\n  private final Elements elements;\n  private final SourceVersion sourceVersion;\n\n  private ExtensionClassTypeSpecBuilder(\n      Context context, String className, String classToExtend, boolean isFinal) {\n    this.context = context;\n    this.className = className;\n    this.classToExtend = classToExtend;\n    this.isFinal = isFinal;\n    this.elements = context.processingEnvironment().getElementUtils();\n    this.sourceVersion = context.processingEnvironment().getSourceVersion();\n  }\n\n  static TypeSpec.Builder extensionClassTypeSpecBuilder(\n      Context context, String className, String classToExtend, boolean isFinal) {\n    return new ExtensionClassTypeSpecBuilder(context, className, classToExtend, isFinal)\n        .extensionClassBuilder();\n  }\n\n  TypeSpec.Builder extensionClassBuilder() {\n    TypeSpec.Builder builder =\n        classBuilder(className)\n            .superclass(superType())\n            .addAnnotations(\n                context.classAnnotationsToCopy(context.autoValueClass()).stream()\n                    .map(AnnotationSpec::get)\n                    .collect(toImmutableList()))\n            .addTypeVariables(annotatedTypeVariableNames())\n            .addModifiers(isFinal ? FINAL : ABSTRACT)\n            .addMethod(constructor());\n    generatedAnnotationSpec(elements, sourceVersion, ToPrettyStringExtension.class)\n        .ifPresent(builder::addAnnotation);\n    return builder;\n  }\n\n  private TypeName superType() {\n    ClassName superType = ClassName.get(context.packageName(), classToExtend);\n    ImmutableList<TypeVariableName> typeVariableNames = typeVariableNames();\n\n    return typeVariableNames.isEmpty()\n        ? superType\n        : ParameterizedTypeName.get(superType, typeVariableNames.toArray(new TypeName[] {}));\n  }\n\n  private ImmutableList<TypeVariableName> typeVariableNames() {\n    return context.autoValueClass().getTypeParameters().stream()\n        .map(TypeVariableName::get)\n        .collect(toImmutableList());\n  }\n\n  private ImmutableList<TypeVariableName> annotatedTypeVariableNames() {\n    return context.autoValueClass().getTypeParameters().stream()\n        .map(\n            p ->\n                TypeVariableName.get(p)\n                    .annotated(\n                        p.getAnnotationMirrors().stream()\n                            .map(AnnotationSpec::get)\n                            .collect(toImmutableList())))\n        .collect(toImmutableList());\n  }\n\n  private MethodSpec constructor() {\n    MethodSpec.Builder constructor = constructorBuilder();\n    // TODO(b/35944623): Replace this with a standard way of avoiding keywords.\n    Set<String> propertyNames = context.properties().keySet();\n    ImmutableMap<String, String> parameterNames =\n        propertyNames.stream()\n            .collect(toImmutableMap(name -> name, name -> generateIdentifier(name, propertyNames)));\n    context\n        .propertyTypes()\n        .forEach(\n            (name, type) ->\n                constructor.addParameter(annotatedType(type), parameterNames.get(name)));\n    String superParams =\n        context.properties().keySet().stream().map(parameterNames::get).collect(joining(\", \"));\n    constructor.addStatement(\"super($L)\", superParams);\n    return constructor.build();\n  }\n\n  private static String generateIdentifier(String name, Set<String> existingNames) {\n    if (!SourceVersion.isKeyword(name)) {\n      return name;\n    }\n    for (int i = 0; ; i++) {\n      String newName = name + i;\n      if (!existingNames.contains(newName)) {\n        return newName;\n      }\n    }\n  }\n\n  /** Translate a {@link TypeMirror} into a {@link TypeName}, including type annotations. */\n  private static TypeName annotatedType(TypeMirror type) {\n    List<AnnotationSpec> annotations =\n        type.getAnnotationMirrors().stream().map(AnnotationSpec::get).collect(toList());\n\n    return TypeName.get(type).annotated(annotations);\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/toprettystring/processor/ToPrettyStringExtension.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.auto.value.extension.toprettystring.processor;\n\nimport static com.google.auto.common.MoreElements.getLocalAndInheritedMethods;\nimport static com.google.auto.common.MoreTypes.asTypeElement;\nimport static com.google.auto.value.extension.toprettystring.processor.ExtensionClassTypeSpecBuilder.extensionClassTypeSpecBuilder;\nimport static com.google.auto.value.extension.toprettystring.processor.ToPrettyStringMethods.toPrettyStringMethod;\nimport static com.google.auto.value.extension.toprettystring.processor.ToPrettyStringMethods.toPrettyStringMethods;\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static com.google.common.collect.Iterables.getLast;\nimport static com.google.common.collect.Iterables.getOnlyElement;\nimport static com.google.common.collect.Sets.intersection;\nimport static com.squareup.javapoet.MethodSpec.methodBuilder;\nimport static javax.lang.model.element.Modifier.FINAL;\nimport static javax.lang.model.element.Modifier.PRIVATE;\nimport static javax.lang.model.element.Modifier.PROTECTED;\nimport static javax.lang.model.element.Modifier.PUBLIC;\nimport static javax.lang.model.element.Modifier.STATIC;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.service.AutoService;\nimport com.google.auto.value.extension.AutoValueExtension;\nimport com.google.auto.value.extension.toprettystring.processor.ToPrettyStringExtension.PrettyPrintableKind.KindVisitor;\nimport com.google.common.base.Equivalence;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.squareup.javapoet.ClassName;\nimport com.squareup.javapoet.CodeBlock;\nimport com.squareup.javapoet.JavaFile;\nimport com.squareup.javapoet.MethodSpec;\nimport com.squareup.javapoet.TypeName;\nimport com.squareup.javapoet.TypeSpec;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.Set;\nimport java.util.function.Supplier;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.Modifier;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.ArrayType;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.PrimitiveType;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.SimpleTypeVisitor8;\nimport javax.lang.model.util.Types;\n\n/**\n * Generates implementations of {@link\n * com.google.auto.value.extension.toprettystring.ToPrettyString} annotated methods in {@link\n * com.google.auto.value.AutoValue} types.\n */\n@AutoService(AutoValueExtension.class)\npublic final class ToPrettyStringExtension extends AutoValueExtension {\n  private static final ImmutableSet<Modifier> INHERITED_VISIBILITY_MODIFIERS =\n      ImmutableSet.of(PUBLIC, PROTECTED);\n  private static final String INDENT = \"  \";\n  private static final String INDENT_METHOD_NAME = \"$indent\";\n  private static final CodeBlock KEY_VALUE_SEPARATOR = CodeBlock.of(\"$S\", \": \");\n\n  @Override\n  public String generateClass(\n      Context context, String className, String classToExtend, boolean isFinal) {\n    TypeSpec type =\n        extensionClassTypeSpecBuilder(context, className, classToExtend, isFinal)\n            .addMethods(toPrettyStringMethodSpecs(context))\n            .build();\n    return JavaFile.builder(context.packageName(), type)\n        .skipJavaLangImports(true)\n        .build()\n        .toString();\n  }\n\n  private ImmutableList<MethodSpec> toPrettyStringMethodSpecs(Context context) {\n    ExecutableElement toPrettyStringMethod = getOnlyElement(toPrettyStringMethods(context));\n    MethodSpec.Builder method =\n        methodBuilder(toPrettyStringMethod.getSimpleName().toString())\n            .addAnnotation(Override.class)\n            .returns(ClassName.get(String.class))\n            .addModifiers(FINAL)\n            .addModifiers(\n                intersection(toPrettyStringMethod.getModifiers(), INHERITED_VISIBILITY_MODIFIERS));\n\n    method.addCode(\"return $S\", context.autoValueClass().getSimpleName() + \" {\");\n    ToPrettyStringImplementation implementation = ToPrettyStringImplementation.create(context);\n    method.addCode(implementation.toStringCodeBlock.build());\n\n    if (!context.properties().isEmpty()) {\n      method.addCode(\" + $S\", \"\\n\");\n    }\n    method.addCode(\" + $S;\\n\", \"}\");\n\n    return ImmutableList.<MethodSpec>builder()\n        .add(method.build())\n        .addAll(implementation.delegateMethods.values())\n        .add(indentMethod())\n        .build();\n  }\n\n  private static MethodSpec indentMethod() {\n    return methodBuilder(INDENT_METHOD_NAME)\n        .addModifiers(PRIVATE, STATIC)\n        .returns(ClassName.get(String.class))\n        .addParameter(TypeName.INT, \"level\")\n        .addStatement(\"$1T builder = new $1T()\", StringBuilder.class)\n        .beginControlFlow(\"for (int i = 0; i < level; i++)\")\n        .addStatement(\"builder.append($S)\", INDENT)\n        .endControlFlow()\n        .addStatement(\"return builder.toString()\")\n        .build();\n  }\n\n  private static class ToPrettyStringImplementation {\n    private final Types types;\n    private final Elements elements;\n\n    private final CodeBlock.Builder toStringCodeBlock = CodeBlock.builder();\n    private final Map<Equivalence.Wrapper<TypeMirror>, MethodSpec> delegateMethods =\n        new LinkedHashMap<>();\n    private final Set<String> methodNames = new HashSet<>();\n\n    private ToPrettyStringImplementation(Context context) {\n      this.types = context.processingEnvironment().getTypeUtils();\n      this.elements = context.processingEnvironment().getElementUtils();\n      // do not submit: what about \"inherited\" static methods?\n      getLocalAndInheritedMethods(context.autoValueClass(), types, elements)\n          .forEach(method -> methodNames.add(method.getSimpleName().toString()));\n    }\n\n    static ToPrettyStringImplementation create(Context context) {\n      ToPrettyStringImplementation implemention = new ToPrettyStringImplementation(context);\n      context\n          .propertyTypes()\n          .forEach(\n              (propertyName, type) -> {\n                String methodName =\n                    context.properties().get(propertyName).getSimpleName().toString();\n                implemention.toStringCodeBlock.add(\n                    \"\\n + $S + $L + $S\",\n                    String.format(\"\\n%s%s = \", INDENT, propertyName),\n                    implemention.format(CodeBlock.of(\"$N()\", methodName), CodeBlock.of(\"1\"), type),\n                    \",\");\n              });\n      return implemention;\n    }\n\n    /**\n     * Returns {@code propertyAccess} formatted for use within the {@link\n     * com.google.auto.value.extension.toprettystring.ToPrettyString} implementation.\n     *\n     * <p>If a helper method is necessary for formatting, a {@link MethodSpec} will be added to\n     * {@link #delegateMethods}.\n     *\n     * @param propertyAccess a reference to the variable that should be formatted.\n     * @param indentAccess a reference to an {@code int} representing how many indent levels should\n     *     be used for this property.\n     * @param type the type of the {@code propertyAccess}.\n     */\n    private CodeBlock format(CodeBlock propertyAccess, CodeBlock indentAccess, TypeMirror type) {\n      PrettyPrintableKind printableKind = type.accept(new KindVisitor(types, elements), null);\n      DelegateMethod delegateMethod = new DelegateMethod(propertyAccess, indentAccess);\n      switch (printableKind) {\n        case PRIMITIVE:\n          return propertyAccess;\n        case REGULAR_OBJECT:\n          return delegateMethod\n              .methodName(\"format\")\n              .invocation(\n                  elements.getTypeElement(\"java.lang.Object\").asType(), () -> reindent(\"toString\"));\n        case HAS_TO_PRETTY_STRING_METHOD:\n          ExecutableElement method =\n              toPrettyStringMethod(asTypeElement(type), types, elements).get();\n          return delegateMethod.invocation(type, () -> reindent(method.getSimpleName()));\n        case ARRAY:\n          TypeMirror componentType = MoreTypes.asArray(type).getComponentType();\n          return delegateMethod.invocation(type, () -> forEachLoopMethodBody(componentType));\n        case COLLECTION:\n          TypeMirror elementType =\n              getOnlyElement(resolvedTypeParameters(type, \"java.util.Collection\"));\n          return delegateMethod.invocation(\n              collectionOf(elementType), () -> forEachLoopMethodBody(elementType));\n        case IMMUTABLE_PRIMITIVE_ARRAY:\n          return delegateMethod.invocation(type, this::forLoopMethodBody);\n        case OPTIONAL:\n        case GUAVA_OPTIONAL:\n          TypeMirror optionalType = getOnlyElement(MoreTypes.asDeclared(type).getTypeArguments());\n          return delegateMethod.invocation(\n              type, () -> optionalMethodBody(optionalType, printableKind));\n        case MAP:\n          return formatMap(type, delegateMethod);\n        case MULTIMAP:\n          return formatMultimap(type, delegateMethod);\n      }\n      throw new AssertionError(printableKind);\n    }\n\n    private CodeBlock formatMap(TypeMirror type, DelegateMethod delegateMethod) {\n      ImmutableList<TypeMirror> typeParameters = resolvedTypeParameters(type, \"java.util.Map\");\n      TypeMirror keyType = typeParameters.get(0);\n      TypeMirror valueType = typeParameters.get(1);\n      return delegateMethod.invocation(\n          mapOf(keyType, valueType), () -> mapMethodBody(keyType, valueType));\n    }\n\n    private CodeBlock formatMultimap(TypeMirror type, DelegateMethod delegateMethod) {\n      ImmutableList<TypeMirror> typeParameters =\n          resolvedTypeParameters(type, \"com.google.common.collect.Multimap\");\n      TypeMirror keyType = typeParameters.get(0);\n      TypeMirror valueType = typeParameters.get(1);\n      return delegateMethod.invocation(\n          multimapOf(keyType, valueType),\n          () -> multimapMethodBody(keyType, collectionOf(valueType)));\n    }\n\n    /**\n     * Parameter object to simplify the branches of {@link #format(CodeBlock, CodeBlock,\n     * TypeMirror)} that call a delegate method.\n     */\n    private class DelegateMethod {\n\n      private final CodeBlock propertyAccess;\n      private final CodeBlock indentAccess;\n      private Optional<String> methodName = Optional.empty();\n\n      DelegateMethod(CodeBlock propertyAccess, CodeBlock indentAccess) {\n        this.propertyAccess = propertyAccess;\n        this.indentAccess = indentAccess;\n      }\n\n      DelegateMethod methodName(String methodName) {\n        this.methodName = Optional.of(methodName);\n        return this;\n      }\n\n      CodeBlock invocation(TypeMirror parameterType, Supplier<CodeBlock> methodBody) {\n        Equivalence.Wrapper<TypeMirror> key = MoreTypes.equivalence().wrap(parameterType);\n        // This doesn't use putIfAbsent because the methodBody supplier could recursively create\n        // new delegate methods. Map.putIfAbsent doesn't support reentrant calls.\n        if (!delegateMethods.containsKey(key)) {\n          delegateMethods.put(\n              key,\n              createMethod(\n                  methodName.orElseGet(() -> newDelegateMethodName(parameterType)),\n                  parameterType,\n                  methodBody));\n        }\n        return CodeBlock.of(\n            \"$N($L, $L)\", delegateMethods.get(key).name, propertyAccess, indentAccess);\n      }\n\n      private String newDelegateMethodName(TypeMirror type) {\n        String prefix = \"format\" + nameForType(type);\n        String methodName = prefix;\n        for (int i = 2; !methodNames.add(methodName); i++) {\n          methodName = prefix + i;\n        }\n        return methodName;\n      }\n\n      private MethodSpec createMethod(\n          String methodName, TypeMirror type, Supplier<CodeBlock> methodBody) {\n        return methodBuilder(methodName)\n            .addModifiers(PRIVATE, STATIC)\n            .returns(ClassName.get(String.class))\n            .addParameter(TypeName.get(type), \"value\")\n            .addParameter(TypeName.INT, \"indentLevel\")\n            .beginControlFlow(\"if (value == null)\")\n            .addStatement(\"return $S\", \"null\")\n            .endControlFlow()\n            .addCode(methodBody.get())\n            .build();\n      }\n    }\n\n    private CodeBlock reindent(CharSequence methodName) {\n      return CodeBlock.builder()\n          .addStatement(\n              \"return value.$1N().replace($2S, $2S + $3N(indentLevel))\",\n              methodName,\n              \"\\n\",\n              INDENT_METHOD_NAME)\n          .build();\n    }\n\n    private CodeBlock forEachLoopMethodBody(TypeMirror elementType) {\n      return loopMethodBody(\n          \"[\",\n          \"]\",\n          CodeBlock.of(\"for ($T element : value)\", elementType),\n          format(CodeBlock.of(\"element\"), CodeBlock.of(\"indentLevel + 1\"), elementType));\n    }\n\n    private CodeBlock forLoopMethodBody() {\n      return loopMethodBody(\n          \"[\",\n          \"]\",\n          CodeBlock.of(\"for (int i = 0; i < value.length(); i++)\"),\n          CodeBlock.of(\"value.get(i)\"));\n    }\n\n    private CodeBlock mapMethodBody(TypeMirror keyType, TypeMirror valueType) {\n      return forEachMapEntryMethodBody(keyType, valueType, \"value\");\n    }\n\n    private CodeBlock multimapMethodBody(TypeMirror keyType, TypeMirror valueType) {\n      return forEachMapEntryMethodBody(keyType, valueType, \"value.asMap()\");\n    }\n\n    private CodeBlock forEachMapEntryMethodBody(\n        TypeMirror keyType, TypeMirror valueType, String propertyAccess) {\n      CodeBlock entryType = CodeBlock.of(\"$T<$T, $T>\", Map.Entry.class, keyType, valueType);\n      return loopMethodBody(\n          \"{\",\n          \"}\",\n          CodeBlock.of(\"for ($L entry : $L.entrySet())\", entryType, propertyAccess),\n          format(CodeBlock.of(\"entry.getKey()\"), CodeBlock.of(\"indentLevel + 1\"), keyType),\n          KEY_VALUE_SEPARATOR,\n          format(CodeBlock.of(\"entry.getValue()\"), CodeBlock.of(\"indentLevel + 1\"), valueType));\n    }\n\n    private CodeBlock loopMethodBody(\n        String openSymbol,\n        String closeSymbol,\n        CodeBlock loopDeclaration,\n        CodeBlock... appendedValues) {\n      ImmutableList<CodeBlock> allAppendedValues =\n          ImmutableList.<CodeBlock>builder()\n              .add(CodeBlock.of(\"$S\", \"\\n\"))\n              .add(CodeBlock.of(\"$N(indentLevel + 1)\", INDENT_METHOD_NAME))\n              .add(appendedValues)\n              .add(CodeBlock.of(\"$S\", \",\"))\n              .build();\n      return CodeBlock.builder()\n          .addStatement(\"$1T builder = new $1T().append($2S)\", StringBuilder.class, openSymbol)\n          .addStatement(\"boolean hasElements = false\")\n          .beginControlFlow(\"$L\", loopDeclaration)\n          .addStatement(\n              \"builder$L\",\n              allAppendedValues.stream()\n                  .map(value -> CodeBlock.of(\".append($L)\", value))\n                  .collect(CodeBlock.joining(\"\")))\n          .addStatement(\"hasElements = true\")\n          .endControlFlow()\n          .beginControlFlow(\"if (hasElements)\")\n          .addStatement(\"builder.append($S).append($N(indentLevel))\", \"\\n\", INDENT_METHOD_NAME)\n          .endControlFlow()\n          .addStatement(\"return builder.append($S).toString()\", closeSymbol)\n          .build();\n    }\n\n    private CodeBlock optionalMethodBody(\n        TypeMirror optionalType, PrettyPrintableKind printableKind) {\n      return CodeBlock.builder()\n          .addStatement(\n              \"return (value.isPresent() ? $L : $S)\",\n              format(CodeBlock.of(\"value.get()\"), CodeBlock.of(\"indentLevel\"), optionalType),\n              printableKind.equals(PrettyPrintableKind.OPTIONAL) ? \"<empty>\" : \"<absent>\")\n          .build();\n    }\n\n    private ImmutableList<TypeMirror> resolvedTypeParameters(\n        TypeMirror propertyType, String interfaceName) {\n      return elements.getTypeElement(interfaceName).getTypeParameters().stream()\n          .map(p -> types.asMemberOf(MoreTypes.asDeclared(propertyType), p))\n          .collect(toImmutableList());\n    }\n\n    private DeclaredType collectionOf(TypeMirror elementType) {\n      return types.getDeclaredType(elements.getTypeElement(\"java.util.Collection\"), elementType);\n    }\n\n    private DeclaredType mapOf(TypeMirror keyType, TypeMirror valueType) {\n      return types.getDeclaredType(elements.getTypeElement(\"java.util.Map\"), keyType, valueType);\n    }\n\n    private DeclaredType multimapOf(TypeMirror keyType, TypeMirror valueType) {\n      return types.getDeclaredType(\n          elements.getTypeElement(\"com.google.common.collect.Multimap\"), keyType, valueType);\n    }\n\n    /** Returns a valid Java identifier for method or variable of type {@code type}. */\n    private String nameForType(TypeMirror type) {\n      return type.accept(\n          new SimpleTypeVisitor8<String, Void>() {\n            @Override\n            public String visitDeclared(DeclaredType type, Void v) {\n              String simpleName = simpleNameForType(type);\n              if (type.getTypeArguments().isEmpty()) {\n                return simpleName;\n              }\n              ImmutableList<String> typeArgumentNames =\n                  type.getTypeArguments().stream()\n                      .map(t -> simpleNameForType(t))\n                      .collect(toImmutableList());\n              if (isMapOrMultimap(type) && typeArgumentNames.size() == 2) {\n                return String.format(\n                    \"%sOf%sTo%s\", simpleName, typeArgumentNames.get(0), typeArgumentNames.get(1));\n              }\n\n              List<String> parts = new ArrayList<>();\n              parts.add(simpleName);\n              parts.add(\"Of\");\n              parts.addAll(typeArgumentNames.subList(0, typeArgumentNames.size() - 1));\n              if (typeArgumentNames.size() > 1) {\n                parts.add(\"And\");\n              }\n              parts.add(getLast(typeArgumentNames));\n              return String.join(\"\", parts);\n            }\n\n            @Override\n            protected String defaultAction(TypeMirror type, Void v) {\n              return simpleNameForType(type);\n            }\n          },\n          null);\n    }\n\n    boolean isMapOrMultimap(TypeMirror type) {\n      TypeMirror mapType = elements.getTypeElement(\"java.util.Map\").asType();\n      if (types.isAssignable(type, types.erasure(mapType))) {\n        return true;\n      }\n      TypeElement multimapElement = elements.getTypeElement(\"com.google.common.collect.Multimap\");\n      return multimapElement != null\n          && types.isAssignable(type, types.erasure(multimapElement.asType()));\n    }\n\n    private String simpleNameForType(TypeMirror type) {\n      return type.accept(\n          new SimpleTypeVisitor8<String, Void>() {\n            @Override\n            public String visitPrimitive(PrimitiveType primitiveType, Void v) {\n              return types.boxedClass(primitiveType).getSimpleName().toString();\n            }\n\n            @Override\n            public String visitArray(ArrayType arrayType, Void v) {\n              return arrayType.getComponentType().accept(this, null) + \"Array\";\n            }\n\n            @Override\n            public String visitDeclared(DeclaredType declaredType, Void v) {\n              return declaredType.asElement().getSimpleName().toString();\n            }\n\n            @Override\n            protected String defaultAction(TypeMirror typeMirror, Void v) {\n              throw new AssertionError(typeMirror);\n            }\n          },\n          null);\n    }\n  }\n\n  enum PrettyPrintableKind {\n    HAS_TO_PRETTY_STRING_METHOD,\n    REGULAR_OBJECT,\n    PRIMITIVE,\n    COLLECTION,\n    ARRAY,\n    IMMUTABLE_PRIMITIVE_ARRAY,\n    OPTIONAL,\n    GUAVA_OPTIONAL,\n    MAP,\n    MULTIMAP,\n    ;\n\n    private static final ImmutableMap<String, PrettyPrintableKind> KINDS_BY_EXACT_TYPE =\n        ImmutableMap.of(\n            \"java.util.Optional\", OPTIONAL,\n            \"com.google.common.base.Optional\", GUAVA_OPTIONAL,\n            \"com.google.common.primitives.ImmutableIntArray\", IMMUTABLE_PRIMITIVE_ARRAY,\n            \"com.google.common.primitives.ImmutableLongArray\", IMMUTABLE_PRIMITIVE_ARRAY,\n            \"com.google.common.primitives.ImmutableDoubleArray\", IMMUTABLE_PRIMITIVE_ARRAY);\n\n    private static final ImmutableMap<String, PrettyPrintableKind> KINDS_BY_SUPERTYPE =\n        ImmutableMap.of(\n            \"java.util.Collection\", COLLECTION,\n            \"java.util.Map\", MAP,\n            \"com.google.common.collect.Multimap\", MULTIMAP);\n\n    static class KindVisitor extends SimpleTypeVisitor8<PrettyPrintableKind, Void> {\n      private final Elements elements;\n      private final Types types;\n\n      KindVisitor(Types types, Elements elements) {\n        super(REGULAR_OBJECT); // default value, covers generic types\n        this.types = types;\n        this.elements = elements;\n      }\n\n      @Override\n      public PrettyPrintableKind visitPrimitive(PrimitiveType primitiveType, Void v) {\n        return PRIMITIVE;\n      }\n\n      @Override\n      public PrettyPrintableKind visitArray(ArrayType arrayType, Void v) {\n        return ARRAY;\n      }\n\n      @Override\n      public PrettyPrintableKind visitDeclared(DeclaredType declaredType, Void v) {\n        TypeElement typeElement = asTypeElement(declaredType);\n        if (toPrettyStringMethod(typeElement, types, elements).isPresent()) {\n          return HAS_TO_PRETTY_STRING_METHOD;\n        }\n        PrettyPrintableKind byExactType =\n            KINDS_BY_EXACT_TYPE.get(typeElement.getQualifiedName().toString());\n        if (byExactType != null) {\n          return byExactType;\n        }\n\n        for (Map.Entry<String, PrettyPrintableKind> entry : KINDS_BY_SUPERTYPE.entrySet()) {\n          TypeElement supertypeElement = elements.getTypeElement(entry.getKey());\n          if (supertypeElement != null\n              && types.isAssignable(declaredType, types.erasure(supertypeElement.asType()))) {\n            return entry.getValue();\n          }\n        }\n\n        return REGULAR_OBJECT;\n      }\n    }\n  }\n\n  @Override\n  public boolean applicable(Context context) {\n    return toPrettyStringMethods(context).size() == 1;\n  }\n\n  @Override\n  public ImmutableSet<ExecutableElement> consumeMethods(Context context) {\n    return toPrettyStringMethods(context);\n  }\n\n  @Override\n  public IncrementalExtensionType incrementalType(ProcessingEnvironment processingEnvironment) {\n    return IncrementalExtensionType.ISOLATING;\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/toprettystring/processor/ToPrettyStringMethods.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.auto.value.extension.toprettystring.processor;\n\nimport static com.google.auto.common.MoreElements.getLocalAndInheritedMethods;\nimport static com.google.auto.value.extension.toprettystring.processor.Annotations.toPrettyStringAnnotation;\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static com.google.common.collect.ImmutableSet.toImmutableSet;\nimport static com.google.common.collect.MoreCollectors.toOptional;\n\nimport com.google.auto.value.extension.AutoValueExtension.Context;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport java.util.Optional;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.Types;\n\nfinal class ToPrettyStringMethods {\n  /**\n   * Returns the {@link com.google.auto.value.extension.toprettystring.ToPrettyString} annotated\n   * methods for an {@code @AutoValue} type.\n   */\n  static ImmutableSet<ExecutableElement> toPrettyStringMethods(Context context) {\n    return context.abstractMethods().stream()\n        .filter(method -> toPrettyStringAnnotation(method).isPresent())\n        .collect(toImmutableSet());\n  }\n\n  /**\n   * Returns the {@link com.google.auto.value.extension.toprettystring.ToPrettyString} annotated\n   * method for a type.\n   */\n  static ImmutableList<ExecutableElement> toPrettyStringMethods(\n      TypeElement element, Types types, Elements elements) {\n    return getLocalAndInheritedMethods(element, types, elements).stream()\n        .filter(method -> toPrettyStringAnnotation(method).isPresent())\n        .collect(toImmutableList());\n  }\n\n  /**\n   * Returns the {@link com.google.auto.value.extension.toprettystring.ToPrettyString} annotated\n   * method for a type.\n   */\n  static Optional<ExecutableElement> toPrettyStringMethod(\n      TypeElement element, Types types, Elements elements) {\n    return toPrettyStringMethods(element, types, elements).stream().collect(toOptional());\n  }\n\n  private ToPrettyStringMethods() {}\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/extension/toprettystring/processor/ToPrettyStringValidator.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.auto.value.extension.toprettystring.processor;\n\nimport static com.google.auto.value.extension.toprettystring.processor.ClassNames.TO_PRETTY_STRING_NAME;\nimport static com.google.auto.value.extension.toprettystring.processor.ToPrettyStringMethods.toPrettyStringMethods;\nimport static java.util.stream.Collectors.joining;\nimport static java.util.stream.Collectors.toCollection;\nimport static javax.lang.model.element.Modifier.STATIC;\nimport static javax.lang.model.util.ElementFilter.methodsIn;\nimport static javax.tools.Diagnostic.Kind.ERROR;\n\nimport com.google.auto.common.MoreElements;\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.service.AutoService;\nimport com.google.common.collect.ImmutableList;\nimport java.util.LinkedHashSet;\nimport java.util.Set;\nimport javax.annotation.processing.AbstractProcessor;\nimport javax.annotation.processing.Messager;\nimport javax.annotation.processing.Processor;\nimport javax.annotation.processing.RoundEnvironment;\nimport javax.annotation.processing.SupportedAnnotationTypes;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.Types;\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessor;\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;\n\n/**\n * An annotation processor that validates {@link\n * com.google.auto.value.extension.toprettystring.ToPrettyString} usage.\n */\n@AutoService(Processor.class)\n@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.ISOLATING)\n@SupportedAnnotationTypes(TO_PRETTY_STRING_NAME)\npublic final class ToPrettyStringValidator extends AbstractProcessor {\n  @Override\n  public boolean process(\n      Set<? extends TypeElement> annotations, RoundEnvironment roundEnvironment) {\n    Types types = processingEnv.getTypeUtils();\n    Elements elements = processingEnv.getElementUtils();\n    TypeElement toPrettyString = elements.getTypeElement(TO_PRETTY_STRING_NAME);\n\n    Set<ExecutableElement> annotatedMethods =\n        methodsIn(roundEnvironment.getElementsAnnotatedWith(toPrettyString));\n    for (ExecutableElement method : annotatedMethods) {\n      validateMethod(method, elements);\n    }\n\n    validateSingleToPrettyStringMethod(annotatedMethods, types, elements);\n\n    return false;\n  }\n\n  private void validateMethod(ExecutableElement method, Elements elements) {\n    ErrorReporter errorReporter = new ErrorReporter(method, processingEnv.getMessager());\n    if (method.getModifiers().contains(STATIC)) {\n      errorReporter.reportError(\"@ToPrettyString methods must be instance methods\");\n    }\n\n    TypeMirror stringType = elements.getTypeElement(\"java.lang.String\").asType();\n    if (!MoreTypes.equivalence().equivalent(method.getReturnType(), stringType)) {\n      errorReporter.reportError(\"@ToPrettyString methods must return String\");\n    }\n\n    if (!method.getParameters().isEmpty()) {\n      errorReporter.reportError(\"@ToPrettyString methods cannot have parameters\");\n    }\n  }\n\n  private void validateSingleToPrettyStringMethod(\n      Set<ExecutableElement> annotatedMethods, Types types, Elements elements) {\n    Set<TypeElement> enclosingTypes =\n        annotatedMethods.stream()\n            .map(Element::getEnclosingElement)\n            .map(MoreElements::asType)\n            .collect(toCollection(LinkedHashSet::new));\n    for (TypeElement enclosingType : enclosingTypes) {\n      ImmutableList<ExecutableElement> methods =\n          toPrettyStringMethods(enclosingType, types, elements);\n      if (methods.size() > 1) {\n        processingEnv\n            .getMessager()\n            .printMessage(\n                ERROR,\n                String.format(\n                    \"%s has multiple @ToPrettyString methods:%s\",\n                    enclosingType.getQualifiedName(), formatMethodList(methods)),\n                enclosingType);\n      }\n    }\n  }\n\n  private String formatMethodList(ImmutableList<ExecutableElement> methods) {\n    return methods.stream().map(this::formatMethodInList).collect(joining());\n  }\n\n  private String formatMethodInList(ExecutableElement method) {\n    return String.format(\n        \"\\n  - %s.%s()\",\n        MoreElements.asType(method.getEnclosingElement()).getQualifiedName(),\n        method.getSimpleName());\n  }\n\n  @Override\n  public SourceVersion getSupportedSourceVersion() {\n    return SourceVersion.latestSupported();\n  }\n\n  private static final class ErrorReporter {\n    private final ExecutableElement method;\n    private final Messager messager;\n\n    ErrorReporter(ExecutableElement method, Messager messager) {\n      this.method = method;\n      this.messager = messager;\n    }\n\n    void reportError(String error) {\n      messager.printMessage(ERROR, error, method);\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/AbortProcessingException.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\n/**\n * Exception thrown when annotation processing should be aborted for the current class. Processing\n * can continue on other classes. Throwing this exception does not cause a compiler error, so either\n * one should explicitly be emitted or it should be clear that the compiler will be producing its\n * own error for other reasons.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@SuppressWarnings(\"serial\")\nclass AbortProcessingException extends RuntimeException {}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/AnnotatedTypeMirror.java",
    "content": "/*\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport com.google.common.base.Joiner;\nimport com.google.common.collect.ImmutableList;\nimport java.util.Objects;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\n\n/**\n * A {@link TypeMirror} and associated annotations.\n *\n * <p>The reason this class is needed is that certain methods in the {@code javax.lang.model} API\n * return modified versions of types, for example {@link javax.lang.model.util.Types#asMemberOf}.\n * Historically, Java compilers were a bit inconsistent about whether those modified types preserve\n * annotations that were in the original type, but the recent consensus is that they should not.\n * Suppose for example if we have this:\n *\n * <pre>{@code\n * interface Parent<T> {\n *   @Nullable T thing();\n * }\n * abstract class Child implements Parent<String> {}\n * }</pre>\n *\n * <p>If we use {@code asMemberOf} to determine what the return type of {@code Child.thing()} is, we\n * will discover it is {@code String}. But we really wanted {@code @Nullable String}. To fix that,\n * we combine the annotations from {@code Parent.thing()} with the resolved type from {@code\n * Child.thing()}.\n *\n * <p>This is only a partial workaround. We aren't able to splice the {@code @Nullable} from {@code\n * List<@Nullable T>} into a type like {@code List<String>} that might be returned from {@code\n * asMemberOf}. Probably a more complete solution would be to adapt the type substitution logic in\n * {@link TypeVariables} so that it can be used instead of {@code Types.asMemberOf} and so that it\n * reattaches annotations on type parameters to the corresponding type arguments, like the {@code\n * List<@Nullable String>} in the example.\n *\n * <p>https://bugs.openjdk.org/browse/JDK-8174126 would potentially provide the basis for a cleaner\n * solution, via a new {@code Types.withAnnotations(type, annotations)} method.\n *\n * <p>This class deliberately does not implement {@link TypeMirror}. Making \"mutant\" {@code\n * TypeMirror} instances is a bit dangerous, because if you give such a thing to one of the {@code\n * javax.lang.model} APIs then you will almost certainly get a {@code ClassCastException}. Those\n * APIs only expect objects that they themselves produced.\n */\nfinal class AnnotatedTypeMirror {\n  private final TypeMirror originalType;\n  private final TypeMirror rewrittenType;\n\n  AnnotatedTypeMirror(TypeMirror originalType, TypeMirror rewrittenType) {\n    this.originalType = originalType;\n    this.rewrittenType = rewrittenType;\n  }\n\n  AnnotatedTypeMirror(TypeMirror type) {\n    this(type, type);\n  }\n\n  ImmutableList<AnnotationMirror> annotations() {\n    return ImmutableList.copyOf(originalType.getAnnotationMirrors());\n  }\n\n  TypeMirror getType() {\n    return rewrittenType;\n  }\n\n  TypeKind getKind() {\n    return rewrittenType.getKind();\n  }\n\n  @Override\n  public String toString() {\n    String annotations = Joiner.on(' ').join(originalType.getAnnotationMirrors());\n    return annotations.isEmpty() ? rewrittenType.toString() : annotations + \" \" + rewrittenType;\n  }\n\n  @Override\n  public boolean equals(Object obj) {\n    if (obj instanceof AnnotatedTypeMirror) {\n      AnnotatedTypeMirror that = (AnnotatedTypeMirror) obj;\n      // This is just for tests. If we wanted to have a genuinely useful `equals` method we would\n      // probably want it to use something like `Types.isSameType`.\n      return this.originalType == that.originalType && this.rewrittenType == that.rewrittenType;\n    }\n    return false;\n  }\n\n  @Override\n  public int hashCode() {\n    return Objects.hash(originalType, rewrittenType);\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/AnnotationOutput.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.value.processor.MissingTypes.MissingTypeException;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.Iterables;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ElementKind;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.SimpleAnnotationValueVisitor8;\nimport javax.tools.Diagnostic;\n\n/**\n * Handling of default values for annotation members.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\nfinal class AnnotationOutput {\n  private AnnotationOutput() {} // There are no instances of this class.\n\n  /**\n   * Visitor that produces a string representation of an annotation value, suitable for inclusion in\n   * a Java source file as an annotation member or as the initializer of a variable of the\n   * appropriate type. The syntax for the two is the same except for annotation members that are\n   * themselves annotations. Within an annotation, an annotation member can be written as\n   * {@code @NestedAnnotation(...)}, while in an initializer it must be written as an object, for\n   * example the construction of an {@code @AutoAnnotation} class. That's why we have this abstract\n   * class and two concrete subclasses.\n   */\n  private abstract static class SourceFormVisitor\n      extends SimpleAnnotationValueVisitor8<Void, StringBuilder> {\n    @Override\n    protected Void defaultAction(Object value, StringBuilder sb) {\n      sb.append(value);\n      return null;\n    }\n\n    @Override\n    public Void visitArray(List<? extends AnnotationValue> values, StringBuilder sb) {\n      sb.append('{');\n      String sep = \"\";\n      for (AnnotationValue value : values) {\n        sb.append(sep);\n        visit(value, sb);\n        sep = \", \";\n      }\n      sb.append('}');\n      return null;\n    }\n\n    @Override\n    public Void visitChar(char c, StringBuilder sb) {\n      appendQuoted(sb, c);\n      return null;\n    }\n\n    @Override\n    public Void visitLong(long i, StringBuilder sb) {\n      sb.append(i).append('L');\n      return null;\n    }\n\n    @Override\n    public Void visitDouble(double d, StringBuilder sb) {\n      if (Double.isNaN(d)) {\n        sb.append(\"Double.NaN\");\n      } else if (d == Double.POSITIVE_INFINITY) {\n        sb.append(\"Double.POSITIVE_INFINITY\");\n      } else if (d == Double.NEGATIVE_INFINITY) {\n        sb.append(\"Double.NEGATIVE_INFINITY\");\n      } else {\n        sb.append(d);\n      }\n      return null;\n    }\n\n    @Override\n    public Void visitFloat(float f, StringBuilder sb) {\n      if (Float.isNaN(f)) {\n        sb.append(\"Float.NaN\");\n      } else if (f == Float.POSITIVE_INFINITY) {\n        sb.append(\"Float.POSITIVE_INFINITY\");\n      } else if (f == Float.NEGATIVE_INFINITY) {\n        sb.append(\"Float.NEGATIVE_INFINITY\");\n      } else {\n        sb.append(f).append('F');\n      }\n      return null;\n    }\n\n    @Override\n    public Void visitEnumConstant(VariableElement c, StringBuilder sb) {\n      sb.append(TypeEncoder.encode(c.asType())).append('.').append(c.getSimpleName());\n      return null;\n    }\n\n    @Override\n    public Void visitString(String s, StringBuilder sb) {\n      appendQuoted(sb, s);\n      return null;\n    }\n\n    @Override\n    public Void visitType(TypeMirror classConstant, StringBuilder sb) {\n      sb.append(TypeEncoder.encode(classConstant)).append(\".class\");\n      return null;\n    }\n  }\n\n  private static class InitializerSourceFormVisitor extends SourceFormVisitor {\n    private final ProcessingEnvironment processingEnv;\n    private final String memberName;\n    private final Element errorContext;\n\n    InitializerSourceFormVisitor(\n        ProcessingEnvironment processingEnv, String memberName, Element errorContext) {\n      this.processingEnv = processingEnv;\n      this.memberName = memberName;\n      this.errorContext = errorContext;\n    }\n\n    @Override\n    public Void visitAnnotation(AnnotationMirror a, StringBuilder sb) {\n      processingEnv\n          .getMessager()\n          .printMessage(\n              Diagnostic.Kind.ERROR,\n              \"@AutoAnnotation cannot yet supply a default value for annotation-valued member '\"\n                  + memberName\n                  + \"'\",\n              errorContext);\n      sb.append(\"null\");\n      return null;\n    }\n  }\n\n  private static class AnnotationSourceFormVisitor extends SourceFormVisitor {\n    @Override\n    public Void visitArray(List<? extends AnnotationValue> values, StringBuilder sb) {\n      if (values.size() == 1) {\n        // We can shorten @Foo(a = {23}) to @Foo(a = 23). For the specific case where `a` is\n        // actually `value`, we'll already have shortened that in visitAnnotation, so effectively we\n        // go from @Foo(value = {23}) to @Foo({23}) to @Foo(23).\n        visit(values.get(0), sb);\n        return null;\n      }\n      return super.visitArray(values, sb);\n    }\n\n    @Override\n    public Void visitAnnotation(AnnotationMirror a, StringBuilder sb) {\n      sb.append('@').append(TypeEncoder.encode(a.getAnnotationType()));\n      ImmutableMap<ExecutableElement, AnnotationValue> map =\n          ImmutableMap.copyOf(a.getElementValues());\n      if (!map.isEmpty()) {\n        sb.append('(');\n        Optional<AnnotationValue> shortForm = shortForm(map);\n        if (shortForm.isPresent()) {\n          this.visit(shortForm.get(), sb);\n        } else {\n          String sep = \"\";\n          for (Map.Entry<ExecutableElement, AnnotationValue> entry : map.entrySet()) {\n            sb.append(sep).append(entry.getKey().getSimpleName()).append(\" = \");\n            sep = \", \";\n            this.visit(entry.getValue(), sb);\n          }\n        }\n        sb.append(')');\n      }\n      return null;\n    }\n\n    // We can shorten @Annot(value = 23) to @Annot(23).\n    private static Optional<AnnotationValue> shortForm(\n        Map<ExecutableElement, AnnotationValue> values) {\n      if (values.size() == 1\n          && Iterables.getOnlyElement(values.keySet()).getSimpleName().contentEquals(\"value\")) {\n        return Optional.of(Iterables.getOnlyElement(values.values()));\n      }\n      return Optional.empty();\n    }\n  }\n\n  /**\n   * Returns a string representation of the given annotation value, suitable for inclusion in a Java\n   * source file as the initializer of a variable of the appropriate type.\n   */\n  static String sourceFormForInitializer(\n      AnnotationValue annotationValue,\n      ProcessingEnvironment processingEnv,\n      String memberName,\n      Element errorContext) {\n    SourceFormVisitor visitor =\n        new InitializerSourceFormVisitor(processingEnv, memberName, errorContext);\n    StringBuilder sb = new StringBuilder();\n    visitor.visit(annotationValue, sb);\n    return sb.toString();\n  }\n\n  /**\n   * Returns a string representation of the given annotation mirror, suitable for inclusion in a\n   * Java source file to reproduce the annotation in source form.\n   */\n  static String sourceFormForAnnotation(AnnotationMirror annotationMirror) {\n    // If a value in the annotation is a reference to a class constant and that class constant is\n    // undefined, javac unhelpfully converts it into a string \"<error>\" and visits that instead. We\n    // want to catch this case and defer processing to allow the class to be defined by another\n    // annotation processor. So we look for annotation elements whose type is Class but whose\n    // reported value is a string. Unfortunately we can't extract the ErrorType corresponding to the\n    // missing class portably. With javac, the AttributeValue is a\n    // com.sun.tools.javac.code.Attribute.UnresolvedClass, which has a public field classType that\n    // is the ErrorType we need, but obviously that's nonportable and fragile.\n    validateClassValues(annotationMirror);\n    StringBuilder sb = new StringBuilder();\n    new AnnotationSourceFormVisitor().visitAnnotation(annotationMirror, sb);\n    return sb.toString();\n  }\n\n  /**\n   * Throws an exception if this annotation contains a value for a Class element that is not\n   * actually a type. The assumption is that the value is the string {@code \"<error>\"} which javac\n   * presents when a Class value is an undefined type.\n   */\n  private static void validateClassValues(AnnotationMirror annotationMirror) {\n    // A class literal can appear in three places:\n    // * for an element of type Class, for example @SomeAnnotation(Foo.class);\n    // * for an element of type Class[], for example @SomeAnnotation({Foo.class, Bar.class});\n    // * inside a nested annotation, for example @SomeAnnotation(@Nested(Foo.class)).\n    // These three possibilities are the three branches of the if/else chain below.\n    annotationMirror\n        .getElementValues()\n        .forEach(\n            (method, value) -> {\n              TypeMirror type = method.getReturnType();\n              if (isJavaLangClass(type) && !(value.getValue() instanceof TypeMirror)) {\n                throw new MissingTypeException(null);\n              } else if (type.getKind().equals(TypeKind.ARRAY)\n                  && isJavaLangClass(MoreTypes.asArray(type).getComponentType())\n                  && value.getValue() instanceof List<?>) {\n                @SuppressWarnings(\"unchecked\") // a List can only be a List<AnnotationValue> here\n                List<AnnotationValue> values = (List<AnnotationValue>) value.getValue();\n                if (values.stream().anyMatch(av -> !(av.getValue() instanceof TypeMirror))) {\n                  throw new MissingTypeException(null);\n                }\n              } else if (type.getKind().equals(TypeKind.DECLARED)\n                  && MoreTypes.asElement(type).getKind().equals(ElementKind.ANNOTATION_TYPE)\n                  && value.getValue() instanceof AnnotationMirror) {\n                validateClassValues((AnnotationMirror) value.getValue());\n              }\n            });\n  }\n\n  private static boolean isJavaLangClass(TypeMirror type) {\n    return type.getKind().equals(TypeKind.DECLARED)\n        && MoreTypes.asTypeElement(type).getQualifiedName().contentEquals(\"java.lang.Class\");\n  }\n\n  private static StringBuilder appendQuoted(StringBuilder sb, String s) {\n    sb.append('\"');\n    for (int i = 0; i < s.length(); i++) {\n      appendEscaped(sb, s.charAt(i));\n    }\n    return sb.append('\"');\n  }\n\n  private static StringBuilder appendQuoted(StringBuilder sb, char c) {\n    sb.append('\\'');\n    appendEscaped(sb, c);\n    return sb.append('\\'');\n  }\n\n  private static void appendEscaped(StringBuilder sb, char c) {\n    switch (c) {\n      case '\\\\':\n      case '\"':\n      case '\\'':\n        sb.append('\\\\').append(c);\n        break;\n      case '\\n':\n        sb.append(\"\\\\n\");\n        break;\n      case '\\r':\n        sb.append(\"\\\\r\");\n        break;\n      case '\\t':\n        sb.append(\"\\\\t\");\n        break;\n      default:\n        if (c < 0x20) {\n          sb.append(String.format(\"\\\\%03o\", (int) c));\n        } else if (c < 0x7f || Character.isLetter(c)) {\n          sb.append(c);\n        } else {\n          sb.append(String.format(\"\\\\u%04x\", (int) c));\n        }\n        break;\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/AutoAnnotationProcessor.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.auto.common.GeneratedAnnotations.generatedAnnotation;\nimport static com.google.auto.value.processor.ClassNames.AUTO_ANNOTATION_NAME;\nimport static com.google.common.collect.Maps.immutableEntry;\nimport static java.util.Comparator.comparing;\nimport static java.util.stream.Collectors.joining;\n\nimport com.google.auto.common.MoreElements;\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.common.SuperficialValidation;\nimport com.google.auto.service.AutoService;\nimport com.google.common.base.Preconditions;\nimport com.google.common.base.Throwables;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.hash.Hashing;\nimport com.google.common.primitives.Primitives;\nimport com.google.errorprone.annotations.FormatMethod;\nimport java.io.IOException;\nimport java.io.Writer;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.Set;\nimport javax.annotation.processing.AbstractProcessor;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.annotation.processing.Processor;\nimport javax.annotation.processing.RoundEnvironment;\nimport javax.annotation.processing.SupportedAnnotationTypes;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ElementKind;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.ArrayType;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.PrimitiveType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.type.WildcardType;\nimport javax.lang.model.util.ElementFilter;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.Types;\nimport javax.tools.Diagnostic;\nimport javax.tools.JavaFileObject;\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessor;\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;\n\n/**\n * Javac annotation processor (compiler plugin) to generate annotation implementations. User code\n * never references this class.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@AutoService(Processor.class)\n@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.ISOLATING)\n@SupportedAnnotationTypes(AUTO_ANNOTATION_NAME)\npublic class AutoAnnotationProcessor extends AbstractProcessor {\n  public AutoAnnotationProcessor() {}\n\n  private Elements elementUtils;\n  private Types typeUtils;\n  private TypeMirror javaLangObject;\n\n  @Override\n  public SourceVersion getSupportedSourceVersion() {\n    return SourceVersion.latestSupported();\n  }\n\n  @Override\n  public ImmutableSet<String> getSupportedOptions() {\n    return ImmutableSet.of(Nullables.NULLABLE_OPTION);\n  }\n\n  @Override\n  public synchronized void init(ProcessingEnvironment processingEnv) {\n    super.init(processingEnv);\n    this.elementUtils = processingEnv.getElementUtils();\n    this.typeUtils = processingEnv.getTypeUtils();\n    this.javaLangObject = elementUtils.getTypeElement(\"java.lang.Object\").asType();\n  }\n\n  /**\n   * Issue a compilation error. This method does not throw an exception, since we want to continue\n   * processing and perhaps report other errors.\n   */\n  @FormatMethod\n  private void reportError(Element e, String msg, Object... msgParams) {\n    String formattedMessage = String.format(msg, msgParams);\n    processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, formattedMessage, e);\n  }\n\n  /**\n   * Issue a compilation error and return an exception that, when thrown, will cause the processing\n   * of this class to be abandoned. This does not prevent the processing of other classes.\n   */\n  @FormatMethod\n  private AbortProcessingException abortWithError(Element e, String msg, Object... msgParams) {\n    reportError(e, msg, msgParams);\n    return new AbortProcessingException();\n  }\n\n  @Override\n  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n    process(roundEnv);\n    return false;\n  }\n\n  private void process(RoundEnvironment roundEnv) {\n    TypeElement autoAnnotation = elementUtils.getTypeElement(AUTO_ANNOTATION_NAME);\n    Collection<? extends Element> annotatedElements =\n        roundEnv.getElementsAnnotatedWith(autoAnnotation);\n    List<ExecutableElement> methods = ElementFilter.methodsIn(annotatedElements);\n    if (!SuperficialValidation.validateElements(methods) || methodsAreOverloaded(methods)) {\n      return;\n    }\n    for (ExecutableElement method : methods) {\n      try {\n        processMethod(method);\n      } catch (AbortProcessingException e) {\n        // We abandoned this type, but continue with the next.\n      } catch (RuntimeException e) {\n        String trace = Throwables.getStackTraceAsString(e);\n        reportError(method, \"@AutoAnnotation processor threw an exception: %s\", trace);\n        throw e;\n      }\n    }\n  }\n\n  private void processMethod(ExecutableElement method) {\n    TypeElement annotationElement = getAnnotationReturnType(method);\n\n    ImmutableSet<Class<?>> wrapperTypesUsedInCollections = wrapperTypesUsedInCollections(method);\n    ImmutableMap<String, ExecutableElement> memberMethods = getMemberMethods(annotationElement);\n    TypeElement methodClass = MoreElements.asType(method.getEnclosingElement());\n    String pkg = TypeSimplifier.packageNameOf(methodClass);\n\n    ImmutableMap<String, AnnotationValue> defaultValues = getDefaultValues(annotationElement);\n    ImmutableMap<String, Member> members = getMembers(method, memberMethods);\n    ImmutableMap<String, Parameter> parameters = getParameters(annotationElement, method, members);\n    validateParameters(annotationElement, method, members, parameters, defaultValues);\n\n    String generatedClassName = generatedClassName(method);\n\n    AutoAnnotationTemplateVars vars = new AutoAnnotationTemplateVars();\n    vars.annotationFullName = annotationElement.toString();\n    vars.annotationName = TypeEncoder.encode(annotationElement.asType());\n    vars.className = generatedClassName;\n    vars.generated = getGeneratedTypeName();\n    vars.members = members;\n    vars.params = parameters;\n    vars.equalsParameterType = equalsParameterType();\n    vars.pkg = pkg;\n    vars.wrapperTypesUsedInCollections = wrapperTypesUsedInCollections;\n    vars.gwtCompatible = isGwtCompatible(annotationElement);\n    vars.serialVersionUID = computeSerialVersionUid(members, parameters);\n    ImmutableMap<String, Integer> invariableHashes = invariableHashes(members, parameters.keySet());\n    vars.invariableHashSum = 0;\n    for (int h : invariableHashes.values()) {\n      vars.invariableHashSum += h;\n    }\n    vars.invariableHashes = invariableHashes.keySet();\n    String text = vars.toText();\n    text = TypeEncoder.decode(text, processingEnv, pkg, annotationElement.asType());\n    text = Reformatter.fixup(text);\n    String fullName = fullyQualifiedName(pkg, generatedClassName);\n    writeSourceFile(fullName, text, methodClass);\n  }\n\n  private String getGeneratedTypeName() {\n    return generatedAnnotation(elementUtils, processingEnv.getSourceVersion())\n        .map(generatedAnnotation -> TypeEncoder.encode(generatedAnnotation.asType()))\n        .orElse(\"\");\n  }\n\n  private String equalsParameterType() {\n    // Unlike AutoValue, we don't currently try to guess a @Nullable based on the methods in your\n    // class. It's the default one or nothing.\n    ImmutableList<AnnotationMirror> equalsParameterAnnotations =\n        Nullables.fromMethods(processingEnv, ImmutableList.of()).nullableTypeAnnotations();\n    return TypeEncoder.encodeWithAnnotations(javaLangObject, equalsParameterAnnotations);\n  }\n\n  /**\n   * Returns the hashCode of the given AnnotationValue, if that hashCode is guaranteed to be always\n   * the same. The hashCode of a String or primitive type never changes. The hashCode of a Class or\n   * an enum constant does potentially change in different runs of the same program. The hashCode of\n   * an array doesn't change if the hashCodes of its elements don't. Although we could have a\n   * similar rule for nested annotation values, we currently don't.\n   */\n  private static Optional<Integer> invariableHash(AnnotationValue annotationValue) {\n    Object value = annotationValue.getValue();\n    if (value instanceof String || Primitives.isWrapperType(value.getClass())) {\n      return Optional.of(value.hashCode());\n    } else if (value instanceof List<?>) {\n      @SuppressWarnings(\"unchecked\") // by specification\n      List<? extends AnnotationValue> list = (List<? extends AnnotationValue>) value;\n      return invariableHash(list);\n    } else {\n      return Optional.empty();\n    }\n  }\n\n  private static Optional<Integer> invariableHash(\n      List<? extends AnnotationValue> annotationValues) {\n    int h = 1;\n    for (AnnotationValue annotationValue : annotationValues) {\n      Optional<Integer> maybeHash = invariableHash(annotationValue);\n      if (!maybeHash.isPresent()) {\n        return Optional.empty();\n      }\n      h = h * 31 + maybeHash.get();\n    }\n    return Optional.of(h);\n  }\n\n  /**\n   * Returns a map from the names of members with invariable hashCodes to the values of those\n   * hashCodes.\n   */\n  private static ImmutableMap<String, Integer> invariableHashes(\n      ImmutableMap<String, Member> members, ImmutableSet<String> parameters) {\n    ImmutableMap.Builder<String, Integer> builder = ImmutableMap.builder();\n    for (String element : members.keySet()) {\n      if (!parameters.contains(element)) {\n        Member member = members.get(element);\n        AnnotationValue annotationValue = member.method.getDefaultValue();\n        Optional<Integer> invariableHash = invariableHash(annotationValue);\n        if (invariableHash.isPresent()) {\n          builder.put(element, (element.hashCode() * 127) ^ invariableHash.get());\n        }\n      }\n    }\n    return builder.build();\n  }\n\n  private boolean methodsAreOverloaded(List<ExecutableElement> methods) {\n    boolean overloaded = false;\n    Set<String> classNames = new HashSet<>();\n    for (ExecutableElement method : methods) {\n      String qualifiedClassName =\n          fullyQualifiedName(\n              MoreElements.getPackage(method).getQualifiedName().toString(),\n              generatedClassName(method));\n      if (!classNames.add(qualifiedClassName)) {\n        overloaded = true;\n        reportError(method, \"@AutoAnnotation methods cannot be overloaded\");\n      }\n    }\n    return overloaded;\n  }\n\n  private String generatedClassName(ExecutableElement method) {\n    TypeElement type = MoreElements.asType(method.getEnclosingElement());\n    String name = type.getSimpleName().toString();\n    while (MoreElements.isType(type.getEnclosingElement())) {\n      type = MoreElements.asType(type.getEnclosingElement());\n      name = type.getSimpleName() + \"_\" + name;\n    }\n    return \"AutoAnnotation_\" + name + \"_\" + method.getSimpleName();\n  }\n\n  private TypeElement getAnnotationReturnType(ExecutableElement method) {\n    TypeMirror returnTypeMirror = method.getReturnType();\n    if (returnTypeMirror.getKind() == TypeKind.DECLARED) {\n      Element returnTypeElement = typeUtils.asElement(method.getReturnType());\n      if (returnTypeElement.getKind() == ElementKind.ANNOTATION_TYPE) {\n        return MoreElements.asType(returnTypeElement);\n      }\n    }\n    throw abortWithError(\n        method,\n        \"Return type of @AutoAnnotation method must be an annotation type, not %s\",\n        returnTypeMirror);\n  }\n\n  private ImmutableMap<String, ExecutableElement> getMemberMethods(TypeElement annotationElement) {\n    ImmutableMap.Builder<String, ExecutableElement> members = ImmutableMap.builder();\n    for (ExecutableElement member :\n        ElementFilter.methodsIn(annotationElement.getEnclosedElements())) {\n      String name = member.getSimpleName().toString();\n      members.put(name, member);\n    }\n    return members.build();\n  }\n\n  private ImmutableMap<String, Member> getMembers(\n      Element context, ImmutableMap<String, ExecutableElement> memberMethods) {\n    ImmutableMap.Builder<String, Member> members = ImmutableMap.builder();\n    for (Map.Entry<String, ExecutableElement> entry : memberMethods.entrySet()) {\n      ExecutableElement memberMethod = entry.getValue();\n      String name = memberMethod.getSimpleName().toString();\n      members.put(name, new Member(processingEnv, context, memberMethod));\n    }\n    return members.build();\n  }\n\n  private ImmutableMap<String, AnnotationValue> getDefaultValues(TypeElement annotationElement) {\n    ImmutableMap.Builder<String, AnnotationValue> defaultValues = ImmutableMap.builder();\n    for (ExecutableElement member :\n        ElementFilter.methodsIn(annotationElement.getEnclosedElements())) {\n      String name = member.getSimpleName().toString();\n      AnnotationValue defaultValue = member.getDefaultValue();\n      if (defaultValue != null) {\n        defaultValues.put(name, defaultValue);\n      }\n    }\n    return defaultValues.build();\n  }\n\n  private ImmutableMap<String, Parameter> getParameters(\n      TypeElement annotationElement, ExecutableElement method, Map<String, Member> members) {\n    ImmutableMap.Builder<String, Parameter> parameters = ImmutableMap.builder();\n    boolean error = false;\n    for (VariableElement parameter : method.getParameters()) {\n      String name = parameter.getSimpleName().toString();\n      Member member = members.get(name);\n      if (member == null) {\n        reportError(\n            parameter,\n            \"@AutoAnnotation method parameter '%s' must have the same name as a member of %s\",\n            name,\n            annotationElement);\n        error = true;\n      } else {\n        TypeMirror parameterType = parameter.asType();\n        TypeMirror memberType = member.getTypeMirror();\n        if (compatibleTypes(parameterType, memberType)) {\n          parameters.put(name, new Parameter(parameterType));\n        } else {\n          reportError(\n              parameter,\n              \"@AutoAnnotation method parameter '%s' has type %s but %s.%s has type %s\",\n              name,\n              parameterType,\n              annotationElement,\n              name,\n              memberType);\n          error = true;\n        }\n      }\n    }\n    if (error) {\n      throw new AbortProcessingException();\n    }\n    return parameters.build();\n  }\n\n  private void validateParameters(\n      TypeElement annotationElement,\n      ExecutableElement method,\n      ImmutableMap<String, Member> members,\n      ImmutableMap<String, Parameter> parameters,\n      ImmutableMap<String, AnnotationValue> defaultValues) {\n    boolean error = false;\n    for (String memberName : members.keySet()) {\n      if (!parameters.containsKey(memberName) && !defaultValues.containsKey(memberName)) {\n        reportError(\n            method,\n            \"@AutoAnnotation method needs a parameter with name '%s' and type %s\"\n                + \" corresponding to %s.%s, which has no default value\",\n            memberName,\n            members.get(memberName).getType(),\n            annotationElement,\n            memberName);\n        error = true;\n      }\n    }\n    if (error) {\n      throw new AbortProcessingException();\n    }\n  }\n\n  /**\n   * Returns true if {@code parameterType} can be used to provide the value of an annotation member\n   * of type {@code memberType}. They must either be the same type, or the member type must be an\n   * array and the parameter type must be a collection of a compatible type.\n   */\n  private boolean compatibleTypes(TypeMirror parameterType, TypeMirror memberType) {\n    if (typeUtils.isAssignable(parameterType, memberType)) {\n      // parameterType assignable to memberType, which in the restricted world of annotations\n      // means they are the same type, or maybe memberType is an annotation type and parameterType\n      // is a subtype of that annotation interface (why would you do that?).\n      return true;\n    }\n    // They're not the same, but we could still consider them compatible if for example\n    // parameterType is List<Integer> and memberType is int[]. We accept any type that is assignable\n    // to Collection<Integer> (in this example).\n    if (memberType.getKind() != TypeKind.ARRAY) {\n      return false;\n    }\n    TypeMirror arrayElementType = MoreTypes.asArray(memberType).getComponentType();\n    TypeMirror wrappedArrayElementType =\n        arrayElementType.getKind().isPrimitive()\n            ? typeUtils.boxedClass((PrimitiveType) arrayElementType).asType()\n            : arrayElementType;\n    TypeElement javaUtilCollection =\n        elementUtils.getTypeElement(Collection.class.getCanonicalName());\n    DeclaredType collectionOfElement =\n        typeUtils.getDeclaredType(javaUtilCollection, wrappedArrayElementType);\n    return typeUtils.isAssignable(parameterType, collectionOfElement);\n  }\n\n  /**\n   * Returns the wrapper types ({@code Integer.class} etc) that are used in collection parameters\n   * like {@code List<Integer>}. This is needed because we will emit a helper method for each such\n   * type, for example to convert {@code Collection<Integer>} into {@code int[]}.\n   */\n  private ImmutableSet<Class<?>> wrapperTypesUsedInCollections(ExecutableElement method) {\n    TypeElement javaUtilCollection = elementUtils.getTypeElement(Collection.class.getName());\n    ImmutableSet.Builder<Class<?>> usedInCollections = ImmutableSet.builder();\n    for (Class<?> wrapper : Primitives.allWrapperTypes()) {\n      DeclaredType collectionOfWrapper =\n          typeUtils.getDeclaredType(javaUtilCollection, getTypeMirror(wrapper));\n      for (VariableElement parameter : method.getParameters()) {\n        if (typeUtils.isAssignable(parameter.asType(), collectionOfWrapper)) {\n          usedInCollections.add(wrapper);\n          break;\n        }\n      }\n    }\n    return usedInCollections.build();\n  }\n\n  private TypeMirror getTypeMirror(Class<?> c) {\n    return elementUtils.getTypeElement(c.getName()).asType();\n  }\n\n  private static boolean isGwtCompatible(TypeElement annotationElement) {\n    return annotationElement.getAnnotationMirrors().stream()\n        .map(mirror -> mirror.getAnnotationType().asElement())\n        .anyMatch(element -> element.getSimpleName().contentEquals(\"GwtCompatible\"));\n  }\n\n  private static String fullyQualifiedName(String pkg, String cls) {\n    return pkg.isEmpty() ? cls : pkg + \".\" + cls;\n  }\n\n  /**\n   * We compute a {@code serialVersionUID} for the generated class based on the names and types of\n   * the annotation members that the {@code @AutoAnnotation} method defines. These are exactly the\n   * names and types of the instance fields in the generated class. So in the common case where the\n   * annotation acquires a new member with a default value, if the {@code @AutoAnnotation} method is\n   * not changed then the generated class will acquire an implementation of the new member method\n   * which just returns the default value. The {@code serialVersionUID} will not change, which makes\n   * sense because the instance fields haven't changed, and instances that were serialized before\n   * the new member was added should deserialize fine. On the other hand, if you then add a\n   * parameter to the {@code @AutoAnnotation} method for the new member, the implementation class\n   * will acquire a new instance field, and we will compute a different {@code serialVersionUID}.\n   * That's because an instance serialized before that change would not have a value for the new\n   * instance field, which would end up zero or null. Users don't expect annotation methods to\n   * return null so that would be bad.\n   *\n   * <p>We could instead add a {@code readObject(ObjectInputStream)} method that would check that\n   * all of the instance fields are really present in the deserialized instance, and perhaps replace\n   * them with their default values from the annotation if not. That seems a lot more complicated\n   * than is justified, though, especially since the instance fields are final and would have to be\n   * set in the deserialized object through reflection.\n   */\n  private static long computeSerialVersionUid(\n      ImmutableMap<String, Member> members, ImmutableMap<String, Parameter> parameters) {\n    // TypeMirror.toString() isn't fully specified so it could potentially differ between\n    // implementations. Our member.getType() string comes from TypeEncoder and is predictable, but\n    // it includes `...` markers around fully-qualified type names, which are used to handle\n    // imports. So we remove those markers below.\n    String namesAndTypesString =\n        members.entrySet().stream()\n            .filter(e -> parameters.containsKey(e.getKey()))\n            .map(e -> immutableEntry(e.getKey(), e.getValue().getType().replace(\"`\", \"\")))\n            .sorted(comparing(Map.Entry::getKey))\n            .map(e -> e.getKey() + \":\" + e.getValue())\n            .collect(joining(\";\"));\n    return Hashing.murmur3_128().hashUnencodedChars(namesAndTypesString).asLong();\n  }\n\n  private void writeSourceFile(String className, String text, TypeElement originatingType) {\n    try {\n      JavaFileObject sourceFile =\n          processingEnv.getFiler().createSourceFile(className, originatingType);\n      try (Writer writer = sourceFile.openWriter()) {\n        writer.write(text);\n      }\n    } catch (IOException e) {\n      // This should really be an error, but we make it a warning in the hope of resisting Eclipse\n      // bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=367599. If that bug manifests, we may get\n      // invoked more than once for the same file, so ignoring the ability to overwrite it is the\n      // right thing to do. If we are unable to write for some other reason, we should get a compile\n      // error later because user code will have a reference to the code we were supposed to\n      // generate (new AutoValue_Foo() or whatever) and that reference will be undefined.\n      processingEnv\n          .getMessager()\n          .printMessage(\n              Diagnostic.Kind.WARNING, \"Could not write generated class \" + className + \": \" + e);\n    }\n  }\n\n  public static class Member {\n    private final ProcessingEnvironment processingEnv;\n    private final Element context;\n    private final ExecutableElement method;\n\n    Member(ProcessingEnvironment processingEnv, Element context, ExecutableElement method) {\n      this.processingEnv = processingEnv;\n      this.context = context;\n      this.method = method;\n    }\n\n    @Override\n    public String toString() {\n      return method.getSimpleName().toString();\n    }\n\n    public String getType() {\n      return TypeEncoder.encode(getTypeMirror());\n    }\n\n    public String getComponentType() {\n      Preconditions.checkState(getTypeMirror().getKind() == TypeKind.ARRAY);\n      ArrayType arrayType = MoreTypes.asArray(getTypeMirror());\n      return TypeEncoder.encode(arrayType.getComponentType());\n    }\n\n    public TypeMirror getTypeMirror() {\n      return method.getReturnType();\n    }\n\n    public TypeKind getKind() {\n      return getTypeMirror().getKind();\n    }\n\n    // Used as part of the hashCode() computation.\n    // See https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/Annotation.html#hashCode--\n    public int getNameHash() {\n      return 127 * toString().hashCode();\n    }\n\n    public boolean isArrayOfClassWithBounds() {\n      if (getTypeMirror().getKind() != TypeKind.ARRAY) {\n        return false;\n      }\n      TypeMirror componentType = MoreTypes.asArray(getTypeMirror()).getComponentType();\n      if (componentType.getKind() != TypeKind.DECLARED) {\n        return false;\n      }\n      DeclaredType declared = MoreTypes.asDeclared(componentType);\n      if (!MoreElements.asType(processingEnv.getTypeUtils().asElement(componentType))\n          .getQualifiedName()\n          .contentEquals(\"java.lang.Class\")) {\n        return false;\n      }\n      if (declared.getTypeArguments().size() != 1) {\n        return false;\n      }\n      TypeMirror parameter = declared.getTypeArguments().get(0);\n      if (parameter.getKind() != TypeKind.WILDCARD) {\n        return true; // for Class<Foo>\n      }\n      WildcardType wildcard = MoreTypes.asWildcard(parameter);\n      // In theory, we should check if getExtendsBound() != Object, since '?' is equivalent to\n      // '? extends Object', but, experimentally, neither javac or ecj will sets getExtendsBound()\n      // to 'Object', so there isn't a point in checking.\n      return wildcard.getSuperBound() != null || wildcard.getExtendsBound() != null;\n    }\n\n    public String getDefaultValue() {\n      AnnotationValue defaultValue = method.getDefaultValue();\n      if (defaultValue == null) {\n        return null;\n      } else {\n        return AnnotationOutput.sourceFormForInitializer(\n            defaultValue, processingEnv, method.getSimpleName().toString(), context);\n      }\n    }\n  }\n\n  public static class Parameter {\n    private final String typeName;\n    private final TypeKind kind;\n\n    Parameter(TypeMirror type) {\n      this.typeName = TypeEncoder.encode(type);\n      this.kind = type.getKind();\n    }\n\n    public String getType() {\n      return typeName;\n    }\n\n    public TypeKind getKind() {\n      return kind;\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/AutoAnnotationTemplateVars.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport com.google.escapevelocity.Template;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n * The variables to substitute into the autoannotation.vm template.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@SuppressWarnings(\"unused\") // the fields in this class are only read via reflection\nclass AutoAnnotationTemplateVars extends TemplateVars {\n  /** The members of the annotation being implemented. */\n  Map<String, AutoAnnotationProcessor.Member> members;\n\n  /**\n   * The parameters in the {@code @AutoAnnotation} method, which are also the constructor parameters\n   * in the generated class.\n   */\n  Map<String, AutoAnnotationProcessor.Parameter> params;\n\n  /**\n   * A string representing the parameter type declaration of the equals(Object) method, including\n   * any annotations.\n   */\n  String equalsParameterType;\n\n  /** The encoded form of the {@code Generated} class, or empty if it is not available. */\n  String generated;\n\n  /**\n   * The package of the class containing the {@code @AutoAnnotation} annotation, which is also the\n   * package where the annotation implementation will be generated.\n   */\n  String pkg;\n\n  /** The simple name of the generated class, like {@code AutoAnnotation_Foo_bar}. */\n  String className;\n\n  /** The name of the annotation interface as it can be referenced in the generated code. */\n  String annotationName;\n\n  /** The fully-qualified name of the annotation interface. */\n  String annotationFullName;\n\n  /**\n   * The wrapper types (like {@code Integer.class}) that are referenced in collection parameters\n   * (like {@code List<Integer>}).\n   */\n  Set<Class<?>> wrapperTypesUsedInCollections;\n\n  /**\n   * True if this annotation is marked {@code @GwtCompatible}. That means that we can't use {@code\n   * clone()} to make a copy of an array.\n   */\n  Boolean gwtCompatible;\n\n  /**\n   * The names of members that are defaulted (not mentioned) in this {@code @AutoAnnotation}, and\n   * whose hash codes are invariable.\n   */\n  Set<String> invariableHashes;\n\n  /** The sum of the hash code contributions from the members in {@link #invariableHashes}. */\n  Integer invariableHashSum;\n\n  /**\n   * A computed {@code serialVersionUID} based on the names and types of the {@code @AutoAnnotation}\n   * method parameters.\n   */\n  Long serialVersionUID;\n\n  private static final Template TEMPLATE = parsedTemplateForResource(\"autoannotation.vm\");\n\n  @Override\n  Template parsedTemplate() {\n    return TEMPLATE;\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/AutoBuilderAnnotationTemplateVars.java",
    "content": "/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport com.google.auto.value.processor.AutoValueishProcessor.Property;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.escapevelocity.Template;\n\n/** The variables to substitute into the autobuilderannotation.vm template. */\nclass AutoBuilderAnnotationTemplateVars extends TemplateVars {\n  private static final Template TEMPLATE = parsedTemplateForResource(\"autobuilderannotation.vm\");\n\n  /** Package of generated class. */\n  String pkg;\n\n  /** The encoding of the {@code Generated} class. Empty if the class is not available. */\n  String generated;\n\n  /** The name of the class to generate. */\n  String className;\n\n  /**\n   * The {@linkplain TypeEncoder#encode encoded} name of the annotation type that the generated code\n   * will build.\n   */\n  String annotationType;\n\n  /**\n   * The {@linkplain TypeEncoder#encode encoded} name of the {@code @AutoBuilder} type that users\n   * will call to build this annotation.\n   */\n  String autoBuilderType;\n\n  /**\n   * The \"properties\" that the builder will build. These are really just names and types, being the\n   * names and types of the annotation elements.\n   */\n  ImmutableSet<Property> props;\n\n  @Override\n  Template parsedTemplate() {\n    return TEMPLATE;\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/AutoBuilderProcessor.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.auto.common.GeneratedAnnotations.generatedAnnotation;\nimport static com.google.auto.common.MoreElements.getLocalAndInheritedMethods;\nimport static com.google.auto.common.MoreElements.getPackage;\nimport static com.google.auto.common.MoreTypes.asDeclared;\nimport static com.google.auto.value.processor.AutoValueProcessor.OMIT_IDENTIFIERS_OPTION;\nimport static com.google.auto.value.processor.ClassNames.AUTO_ANNOTATION_NAME;\nimport static com.google.auto.value.processor.ClassNames.AUTO_BUILDER_NAME;\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static com.google.common.collect.ImmutableMap.toImmutableMap;\nimport static com.google.common.collect.ImmutableSet.toImmutableSet;\nimport static java.math.RoundingMode.CEILING;\nimport static java.util.stream.Collectors.joining;\nimport static java.util.stream.Collectors.toMap;\nimport static javax.lang.model.util.ElementFilter.constructorsIn;\nimport static javax.lang.model.util.ElementFilter.methodsIn;\n\nimport com.google.auto.common.AnnotationMirrors;\nimport com.google.auto.common.AnnotationValues;\nimport com.google.auto.common.MoreElements;\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.common.Visibility;\nimport com.google.auto.service.AutoService;\nimport com.google.auto.value.processor.MissingTypes.MissingTypeException;\nimport com.google.common.base.Ascii;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.math.IntMath;\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.io.UncheckedIOException;\nimport java.lang.reflect.Field;\nimport java.util.AbstractMap.SimpleEntry;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.NavigableSet;\nimport java.util.Optional;\nimport java.util.Set;\nimport java.util.TreeMap;\nimport java.util.TreeSet;\nimport java.util.stream.Stream;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.annotation.processing.Processor;\nimport javax.annotation.processing.SupportedAnnotationTypes;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ElementKind;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.Modifier;\nimport javax.lang.model.element.PackageElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.tools.JavaFileObject;\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessor;\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;\n\n/**\n * Javac annotation processor (compiler plugin) for builders; user code never references this class.\n *\n * @see <a href=\"https://github.com/google/auto/tree/main/value\">AutoValue User's Guide</a>\n * @author Éamonn McManus\n */\n@AutoService(Processor.class)\n@SupportedAnnotationTypes(AUTO_BUILDER_NAME)\n@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.ISOLATING)\npublic class AutoBuilderProcessor extends AutoValueishProcessor {\n  private static final String ALLOW_OPTION = \"com.google.auto.value.AutoBuilderIsUnstable\";\n  private static final String AUTO_ANNOTATION_CLASS_PREFIX = \"AutoBuilderAnnotation_\";\n\n  public AutoBuilderProcessor() {\n    super(AUTO_BUILDER_NAME, /* appliesToInterfaces= */ true);\n  }\n\n  @Override\n  public Set<String> getSupportedOptions() {\n    return ImmutableSet.of(OMIT_IDENTIFIERS_OPTION, ALLOW_OPTION);\n  }\n\n  private TypeMirror javaLangVoid;\n  private KotlinMetadata kotlinMetadata;\n\n  @Override\n  public synchronized void init(ProcessingEnvironment processingEnv) {\n    super.init(processingEnv);\n    javaLangVoid = elementUtils().getTypeElement(\"java.lang.Void\").asType();\n    kotlinMetadata = new KotlinMetadata(errorReporter());\n  }\n\n  // The handling of @AutoBuilder to generate annotation implementations needs some explanation.\n  // Suppose we have this:\n  //\n  //   public class Annotations {\n  //     @interface MyAnnot {...}\n  //\n  //     @AutoBuilder(ofClass = MyAnnot.class)\n  //     public interface MyAnnotBuilder {\n  //       ...\n  //       MyAnnot build();\n  //     }\n  //\n  //     public static MyAnnotBuilder myAnnotBuilder() {\n  //       return new AutoBuilder_Annotations_MyAnnotBuilder();\n  //     }\n  //   }\n  //\n  // Then we will detect that the ofClass type is an annotation. Since annotations can have neither\n  // constructors nor static methods, we know this isn't a regular @AutoBuilder. We want to\n  // generate an implementation of the MyAnnot annotation, and we know we can do that if we have a\n  // suitable @AutoAnnotation method. So we generate:\n  //\n  //   class AutoBuilderAnnotation_Annotations_MyAnnotBuilder {\n  //     @AutoAnnotation\n  //     static MyAnnot newAnnotation(...) {\n  //       return new AutoAnnotation_AutoBuilderAnnotation_Annotations_MyAnnotBuilder_newAnnotation(\n  //           ...);\n  //     }\n  //   }\n  //\n  // We also \"defer\" MyAnnotBuilder so that it will be considered again on the next round. At that\n  // point the method AutoBuilderAnnotation_Annotations_MyAnnotBuilder.newAnnotation will exist, and\n  // we just need to tweak the handling of MyAnnotBuilder so that it behaves as if it were:\n  //\n  //   @AutoBuilder(\n  //       callMethod = newAnnotation,\n  //       ofClass = AutoBuilderAnnotation_Annotations_MyAnnotBuilder.class)\n  //   interface MyAnnotBuilder {...}\n  //\n  // Using AutoAnnotation and AutoBuilder together you'd write\n  //\n  // @AutoAnnotation static MyAnnot newAnnotation(...) { ... }\n  //\n  // @AutoBuilder(callMethod = \"newAnnotation\", ofClass = Some.class)\n  // interface MyAnnotBuilder { ... }\n  //\n  // If you set ofClass to an annotation class, AutoBuilder generates the @AutoAnnotation method for\n  // you and then acts as if your @AutoBuilder annotation pointed to it.\n\n  @Override\n  void processType(TypeElement autoBuilderType) {\n    if (processingEnv.getOptions().containsKey(ALLOW_OPTION)) {\n      errorReporter().reportWarning(autoBuilderType, \"The -A%s option is obsolete\", ALLOW_OPTION);\n    }\n    // The annotation is guaranteed to be present by the contract of Processor#process\n    AnnotationMirror autoBuilderAnnotation =\n        getAnnotationMirror(autoBuilderType, AUTO_BUILDER_NAME).get();\n    TypeElement ofClass = getOfClass(autoBuilderType, autoBuilderAnnotation);\n    checkModifiersIfNested(ofClass, autoBuilderType, \"AutoBuilder ofClass\");\n    String callMethod = findCallMethodValue(autoBuilderAnnotation);\n    if (ofClass.getKind() == ElementKind.ANNOTATION_TYPE) {\n      buildAnnotation(autoBuilderType, ofClass, callMethod);\n    } else {\n      processType(autoBuilderType, ofClass, callMethod);\n    }\n  }\n\n  private void processType(TypeElement autoBuilderType, TypeElement ofClass, String callMethod) {\n    ImmutableSet<ExecutableElement> methods =\n        abstractMethodsIn(\n            getLocalAndInheritedMethods(autoBuilderType, typeUtils(), elementUtils()));\n    Executable executable = findExecutable(ofClass, callMethod, autoBuilderType, methods);\n    BuilderSpec builderSpec = new BuilderSpec(ofClass, processingEnv, errorReporter());\n    BuilderSpec.Builder builder = builderSpec.new Builder(autoBuilderType);\n    TypeMirror builtType = executable.builtType();\n    ImmutableMap<String, String> propertyInitializers =\n        propertyInitializers(autoBuilderType, executable);\n    Nullables nullables = Nullables.fromMethods(processingEnv, methods);\n    Optional<BuilderMethodClassifier<VariableElement>> maybeClassifier =\n        BuilderMethodClassifierForAutoBuilder.classify(\n            methods,\n            errorReporter(),\n            processingEnv,\n            executable,\n            builtType,\n            autoBuilderType,\n            propertyInitializers.keySet(),\n            nullables);\n    if (!maybeClassifier.isPresent() || errorReporter().errorCount() > 0) {\n      // We've already output one or more error messages.\n      return;\n    }\n    BuilderMethodClassifier<VariableElement> classifier = maybeClassifier.get();\n    ImmutableMap<String, String> propertyToGetterName =\n        propertyToGetterName(executable, autoBuilderType);\n    AutoBuilderTemplateVars vars = new AutoBuilderTemplateVars();\n    vars.props = propertySet(executable, propertyToGetterName, propertyInitializers, nullables);\n    builder.defineVars(vars, classifier);\n    vars.identifiers = !processingEnv.getOptions().containsKey(OMIT_IDENTIFIERS_OPTION);\n    String generatedClassName = generatedClassName(autoBuilderType, \"AutoBuilder_\");\n    vars.builderName = TypeSimplifier.simpleNameOf(generatedClassName);\n    vars.builtType = TypeEncoder.encode(builtType);\n    vars.builderAnnotations = copiedClassAnnotations(autoBuilderType);\n    Optional<String> forwardingClassName = maybeForwardingClass(autoBuilderType, executable);\n    vars.build =\n        forwardingClassName\n            .map(n -> TypeSimplifier.simpleNameOf(n) + \".of\")\n            .orElseGet(executable::invoke);\n    vars.toBuilderConstructor = !propertyToGetterName.isEmpty();\n    vars.toBuilderMethods = ImmutableList.of();\n    defineSharedVarsForType(autoBuilderType, ImmutableSet.of(), nullables, vars);\n    String text = vars.toText();\n    text = TypeEncoder.decode(text, processingEnv, vars.pkg, autoBuilderType.asType());\n    text = Reformatter.fixup(text);\n    writeSourceFile(generatedClassName, text, autoBuilderType);\n    forwardingClassName.ifPresent(\n        n -> generateForwardingClass(n, executable, builtType, autoBuilderType));\n  }\n\n  /**\n   * Generates a class that will call the synthetic Kotlin constructor that is used to specify which\n   * optional parameters are defaulted. Because it is synthetic, it can't be called from Java source\n   * code. Instead, Java source code calls the {@code of} method in the class we generate here.\n   */\n  private void generateForwardingClass(\n      String forwardingClassName,\n      Executable executable,\n      TypeMirror builtType,\n      TypeElement autoBuilderType) {\n    // The synthetic constructor has the same parameters as the user-written constructor, plus as\n    // many `int` bitmasks as are needed to have one bit for each of those parameters, plus a dummy\n    // parameter of type kotlin.jvm.internal.DefaultConstructorMarker to avoid confusion with a\n    // constructor that might have its own `int` parameters where the bitmasks are.\n    // This ABI is not publicly specified (as far as we know) but JetBrains has confirmed orally\n    // that it unlikely to change, and if it does it will be in a backward-compatible way.\n    ImmutableList.Builder<TypeMirror> constructorParameters = ImmutableList.builder();\n    executable.parameters().stream().map(Element::asType).forEach(constructorParameters::add);\n    int bitmaskCount = IntMath.divide(executable.parameters().size(), 32, CEILING);\n    constructorParameters.addAll(\n        Collections.nCopies(bitmaskCount, typeUtils().getPrimitiveType(TypeKind.INT)));\n    String marker = \"kot\".concat(\"lin.jvm.internal.DefaultConstructorMarker\"); // defeat shading\n    constructorParameters.add(elementUtils().getTypeElement(marker).asType());\n    byte[] classBytes =\n        new ForwardingClassGenerator(typeUtils())\n            .makeConstructorForwarder(\n                forwardingClassName, asDeclared(builtType), constructorParameters.build());\n    try {\n      JavaFileObject trampoline =\n          processingEnv.getFiler().createClassFile(forwardingClassName, autoBuilderType);\n      try (OutputStream out = trampoline.openOutputStream()) {\n        out.write(classBytes);\n      }\n    } catch (IOException e) {\n      throw new UncheckedIOException(e);\n    }\n  }\n\n  private Optional<String> maybeForwardingClass(\n      TypeElement autoBuilderType, Executable executable) {\n    return executable.hasOptionalParameters()\n        ? Optional.of(generatedClassName(autoBuilderType, \"AutoBuilderBridge_\"))\n        : Optional.empty();\n  }\n\n  private ImmutableSet<Property> propertySet(\n      Executable executable,\n      Map<String, String> propertyToGetterName,\n      ImmutableMap<String, String> builderInitializers,\n      Nullables nullables) {\n    // Fix any parameter names that are reserved words in Java. Java source code can't have\n    // such parameter names, but Kotlin code might, for example.\n    Map<VariableElement, String> identifiers =\n        executable.parameters().stream().collect(toMap(v -> v, v -> v.getSimpleName().toString()));\n    fixReservedIdentifiers(identifiers);\n    return executable.parameters().stream()\n        .map(\n            v -> {\n              String name = v.getSimpleName().toString();\n              Property p =\n                  newProperty(\n                      v,\n                      identifiers.get(v),\n                      propertyToGetterName.get(name),\n                      Optional.ofNullable(builderInitializers.get(name)),\n                      executable.isOptional(name),\n                      nullables);\n              if (p.isNullable() && v.asType().getKind().isPrimitive()) {\n                errorReporter()\n                    .reportError(\n                        v, \"[AutoBuilderNullPrimitive] Primitive types cannot be @Nullable\");\n              }\n              return p;\n            })\n        .collect(toImmutableSet());\n  }\n\n  private Property newProperty(\n      VariableElement var,\n      String identifier,\n      String getterName,\n      Optional<String> builderInitializer,\n      boolean hasDefault,\n      Nullables nullables) {\n    String name = var.getSimpleName().toString();\n    TypeMirror type = var.asType();\n    Optional<String> nullableAnnotation = nullableAnnotationFor(var, var.asType());\n    return new Property(\n        name,\n        identifier,\n        TypeEncoder.encodeWithAnnotations(type),\n        new AnnotatedTypeMirror(type),\n        nullableAnnotation,\n        nullables,\n        getterName,\n        builderInitializer,\n        hasDefault);\n  }\n\n  private ImmutableMap<String, String> propertyInitializers(\n      TypeElement autoBuilderType, Executable executable) {\n    boolean autoAnnotation =\n        MoreElements.getAnnotationMirror(executable.executableElement(), AUTO_ANNOTATION_NAME)\n            .isPresent();\n    if (!autoAnnotation) {\n      return ImmutableMap.of();\n    }\n    // We expect the return type of an @AutoAnnotation method to be an annotation type. If it isn't,\n    // AutoAnnotation will presumably complain, so we don't need to complain further.\n    TypeMirror returnType = executable.builtType();\n    if (!returnType.getKind().equals(TypeKind.DECLARED)) {\n      return ImmutableMap.of();\n    }\n    // This might not actually be an annotation (if the code is wrong), but if that's the case we\n    // just won't see any contained ExecutableElement where getDefaultValue() returns something.\n    TypeElement annotation = MoreTypes.asTypeElement(returnType);\n    ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();\n    for (ExecutableElement method : methodsIn(annotation.getEnclosedElements())) {\n      AnnotationValue defaultValue = method.getDefaultValue();\n      if (defaultValue != null) {\n        String memberName = method.getSimpleName().toString();\n        builder.put(\n            memberName,\n            AnnotationOutput.sourceFormForInitializer(\n                defaultValue, processingEnv, memberName, autoBuilderType));\n      }\n    }\n    return builder.build();\n  }\n\n  /**\n   * Returns a map from property names to the corresponding getters in the built type. The built\n   * type is the return type of the given {@code executable}, and the property names are the names\n   * of its parameters. If the return type is a {@link DeclaredType} {@code Foo} and if every\n   * property name {@code bar} matches a method {@code bar()} or {@code getBar()} in {@code Foo},\n   * then the method returns a map where {@code bar} maps to {@code bar} or {@code getBar}. If these\n   * conditions are not met then the method returns an empty map.\n   *\n   * <p>The method name match is case-insensitive, so we will also accept {@code baR()} or {@code\n   * getbar()}. For a property of type {@code boolean}, we also accept {@code isBar()} (or {@code\n   * isbar()} etc).\n   *\n   * <p>The return type of each getter method must match the type of the corresponding parameter\n   * exactly. This will always be true for our principal use cases, Java records and Kotlin data\n   * classes. For other use cases, we may in the future accept getters where we know how to convert,\n   * for example if the getter has type {@code ImmutableList<Baz>} and the parameter has type {@code\n   * Baz[]}. We already have similar logic for the parameter types of builder setters.\n   */\n  private ImmutableMap<String, String> propertyToGetterName(\n      Executable executable, TypeElement autoBuilderType) {\n    TypeMirror builtType = executable.builtType();\n    if (builtType.getKind() != TypeKind.DECLARED) {\n      return ImmutableMap.of();\n    }\n    TypeElement type = MoreTypes.asTypeElement(builtType);\n    Map<String, ExecutableElement> nameToMethod =\n        MoreElements.getLocalAndInheritedMethods(type, typeUtils(), elementUtils()).stream()\n            .filter(m -> m.getParameters().isEmpty())\n            .filter(m -> !m.getModifiers().contains(Modifier.STATIC))\n            .filter(m -> visibleFrom(autoBuilderType, getPackage(autoBuilderType)))\n            .collect(\n                toMap(\n                    m -> m.getSimpleName().toString(),\n                    m -> m,\n                    (a, b) -> a,\n                    () -> new TreeMap<>(String.CASE_INSENSITIVE_ORDER)));\n    ImmutableMap<String, String> propertyToGetterName =\n        executable.parameters().stream()\n            .map(\n                param -> {\n                  String name = param.getSimpleName().toString();\n                  // Parameter name is `bar`; we look for `bar()` and `getBar()` (or `getbar()` etc)\n                  // in that order. If `bar` is boolean we also look for `isBar()`.\n                  ExecutableElement getter = nameToMethod.get(name);\n                  if (getter == null) {\n                    getter = nameToMethod.get(\"get\" + name);\n                    if (getter == null && param.asType().getKind() == TypeKind.BOOLEAN) {\n                      getter = nameToMethod.get(\"is\" + name);\n                    }\n                  }\n                  if (getter != null\n                      && !typeUtils().isAssignable(getter.getReturnType(), param.asType())\n                      && !MoreTypes.equivalence()\n                          .equivalent(getter.getReturnType(), param.asType())) {\n                    // TODO(b/268680785): we should not need to have two type checks here\n                    getter = null;\n                  }\n                  return new SimpleEntry<>(name, getter);\n                })\n            .filter(entry -> entry.getValue() != null)\n            .collect(\n                toImmutableMap(\n                    Map.Entry::getKey, entry -> entry.getValue().getSimpleName().toString()));\n    return (propertyToGetterName.size() == executable.parameters().size())\n        ? propertyToGetterName\n        : ImmutableMap.of();\n  }\n\n  private Executable findExecutable(\n      TypeElement ofClass,\n      String callMethod,\n      TypeElement autoBuilderType,\n      ImmutableSet<ExecutableElement> methodsInAutoBuilderType) {\n    ImmutableList<Executable> executables =\n        findRelevantExecutables(ofClass, callMethod, autoBuilderType);\n    String description =\n        callMethod.isEmpty() ? \"constructor\" : \"static method named \\\"\" + callMethod + \"\\\"\";\n    switch (executables.size()) {\n      case 0:\n        throw errorReporter()\n            .abortWithError(\n                autoBuilderType,\n                \"[AutoBuilderNoVisible] No visible %s for %s\",\n                description,\n                ofClass);\n      case 1:\n        return executables.get(0);\n      default:\n        return matchingExecutable(\n            autoBuilderType, executables, methodsInAutoBuilderType, description);\n    }\n  }\n\n  private ImmutableList<Executable> findRelevantExecutables(\n      TypeElement ofClass, String callMethod, TypeElement autoBuilderType) {\n    Optional<AnnotationMirror> kotlinMetadataAnnotation =\n        kotlinMetadata.kotlinMetadataAnnotation(ofClass);\n    List<? extends Element> elements = ofClass.getEnclosedElements();\n    Stream<Executable> relevantExecutables =\n        callMethod.isEmpty()\n            ? kotlinMetadataAnnotation\n                .map(a -> kotlinMetadata.kotlinConstructorsIn(a, ofClass).stream())\n                .orElseGet(() -> constructorsIn(elements).stream().map(Executable::of))\n            : methodsIn(elements).stream()\n                .filter(m -> m.getSimpleName().contentEquals(callMethod))\n                .filter(m -> m.getModifiers().contains(Modifier.STATIC))\n                .map(Executable::of);\n    return relevantExecutables\n        .filter(e -> visibleFrom(e.executableElement(), getPackage(autoBuilderType)))\n        .collect(toImmutableList());\n  }\n\n  private Executable matchingExecutable(\n      TypeElement autoBuilderType,\n      List<Executable> executables,\n      ImmutableSet<ExecutableElement> methodsInAutoBuilderType,\n      String description) {\n    // There's more than one visible executable (constructor or method). We try to find the one that\n    // corresponds to the methods in the @AutoBuilder interface. This is a bit approximate. We're\n    // basically just looking for an executable where all the parameter names correspond to setters\n    // or property builders in the interface. We might find out after choosing one that it is wrong\n    // for whatever reason (types don't match, spurious methods, etc). But it is likely that if the\n    // names are all accounted for in the methods, and if there's no other matching executable with\n    // more parameters, then this is indeed the one we want. If we later get errors when we try to\n    // analyze the interface in detail, those are probably legitimate errors and not because we\n    // picked the wrong executable.\n    ImmutableList<Executable> matches =\n        executables.stream()\n            .filter(x -> executableMatches(x, methodsInAutoBuilderType))\n            .collect(toImmutableList());\n    switch (matches.size()) {\n      case 0:\n        throw errorReporter()\n            .abortWithError(\n                autoBuilderType,\n                \"[AutoBuilderNoMatch] Property names do not correspond to the parameter names of\"\n                    + \" any %s:\\n%s\",\n                description,\n                executableListString(executables));\n      case 1:\n        return matches.get(0);\n      default:\n        // More than one match, let's see if we can find the best one.\n    }\n    int max = matches.stream().mapToInt(e -> e.parameters().size()).max().getAsInt();\n    ImmutableList<Executable> maxMatches =\n        matches.stream().filter(c -> c.parameters().size() == max).collect(toImmutableList());\n    if (maxMatches.size() > 1) {\n      throw errorReporter()\n          .abortWithError(\n              autoBuilderType,\n              \"[AutoBuilderAmbiguous] Property names correspond to more than one %s:\\n%s\",\n              description,\n              executableListString(maxMatches));\n    }\n    return maxMatches.get(0);\n  }\n\n  private String executableListString(List<Executable> executables) {\n    return executables.stream().map(Object::toString).collect(joining(\"\\n  \", \"  \", \"\"));\n  }\n\n  private boolean executableMatches(\n      Executable executable, ImmutableSet<ExecutableElement> methodsInAutoBuilderType) {\n    // Start with the complete set of parameter names and remove them one by one as we find\n    // corresponding methods. We ignore case, under the assumption that it is unlikely that a case\n    // difference is going to allow a candidate to match when another one is better.\n    // A parameter named foo could be matched by methods like this:\n    //    X foo(Y)\n    //    X setFoo(Y)\n    //    X fooBuilder()\n    //    X fooBuilder(Y)\n    // There are further constraints, including on the types X and Y, that will later be imposed by\n    // BuilderMethodClassifier, but here we just require that there be at least one method with\n    // one of these shapes for foo.\n    NavigableSet<String> parameterNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);\n    parameterNames.addAll(executable.parameterNames());\n    for (ExecutableElement method : methodsInAutoBuilderType) {\n      String name = method.getSimpleName().toString();\n      if (name.endsWith(\"Builder\")) {\n        String property = name.substring(0, name.length() - \"Builder\".length());\n        parameterNames.remove(property);\n      }\n      if (method.getParameters().size() == 1) {\n        parameterNames.remove(name);\n        if (name.startsWith(\"set\")) {\n          parameterNames.remove(name.substring(3));\n        }\n      }\n      if (parameterNames.isEmpty()) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  private boolean visibleFrom(Element element, PackageElement fromPackage) {\n    Visibility visibility = Visibility.effectiveVisibilityOfElement(element);\n    switch (visibility) {\n      case PUBLIC:\n        return true;\n      case PROTECTED:\n      // We care about whether the constructor is visible from the generated class. The generated\n      // class is never going to be a subclass of the class containing the constructor, so\n      // protected and default access are equivalent.\n      case DEFAULT:\n        return getPackage(element).equals(fromPackage);\n      default:\n        return false;\n    }\n  }\n\n  private static final ElementKind ELEMENT_KIND_RECORD = elementKindRecord();\n\n  private static ElementKind elementKindRecord() {\n    try {\n      Field record = ElementKind.class.getField(\"RECORD\");\n      return (ElementKind) record.get(null);\n    } catch (ReflectiveOperationException e) {\n      // OK: we must be on a JDK version that predates this.\n      return null;\n    }\n  }\n\n  private TypeElement getOfClass(\n      TypeElement autoBuilderType, AnnotationMirror autoBuilderAnnotation) {\n    TypeElement ofClassValue = findOfClassValue(autoBuilderAnnotation);\n    boolean isDefault = typeUtils().isSameType(ofClassValue.asType(), javaLangVoid);\n    if (!isDefault) {\n      return ofClassValue;\n    }\n    Element enclosing = autoBuilderType.getEnclosingElement();\n    ElementKind enclosingKind = enclosing.getKind();\n    if (enclosing.getKind() != ElementKind.CLASS && enclosingKind != ELEMENT_KIND_RECORD) {\n      errorReporter()\n          .abortWithError(\n              autoBuilderType,\n              \"[AutoBuilderEnclosing] @AutoBuilder must specify ofClass=Something.class or it\"\n                  + \" must be nested inside the class to be built; actually nested inside %s %s.\",\n              Ascii.toLowerCase(enclosingKind.name()),\n              enclosing);\n    }\n    return MoreElements.asType(enclosing);\n  }\n\n  private TypeElement findOfClassValue(AnnotationMirror autoBuilderAnnotation) {\n    AnnotationValue ofClassValue =\n        AnnotationMirrors.getAnnotationValue(autoBuilderAnnotation, \"ofClass\");\n    Object value = ofClassValue.getValue();\n    if (value instanceof TypeMirror) {\n      TypeMirror ofClassType = (TypeMirror) value;\n      switch (ofClassType.getKind()) {\n        case DECLARED:\n          return MoreTypes.asTypeElement(ofClassType);\n        case ERROR:\n          throw new MissingTypeException(MoreTypes.asError(ofClassType));\n        default:\n          break;\n      }\n    }\n    throw new MissingTypeException(null);\n  }\n\n  private String findCallMethodValue(AnnotationMirror autoBuilderAnnotation) {\n    AnnotationValue callMethodValue =\n        AnnotationMirrors.getAnnotationValue(autoBuilderAnnotation, \"callMethod\");\n    return AnnotationValues.getString(callMethodValue);\n  }\n\n  @Override\n  Optional<String> nullableAnnotationForMethod(ExecutableElement propertyMethod) {\n    // TODO(b/183005059): implement\n    return Optional.empty();\n  }\n\n  private void buildAnnotation(\n      TypeElement autoBuilderType, TypeElement annotationType, String callMethod) {\n    if (!callMethod.isEmpty()) {\n      errorReporter()\n          .abortWithError(\n              autoBuilderType,\n              \"[AutoBuilderAnnotationMethod] @AutoBuilder for an annotation must have an empty\"\n                  + \" callMethod, not \\\"%s\\\"\",\n              callMethod);\n    }\n    String autoAnnotationClassName =\n        generatedClassName(autoBuilderType, AUTO_ANNOTATION_CLASS_PREFIX);\n    TypeElement autoAnnotationClass = elementUtils().getTypeElement(autoAnnotationClassName);\n    if (autoAnnotationClass != null) {\n      processType(autoBuilderType, autoAnnotationClass, \"newAnnotation\");\n      return;\n    }\n    AutoBuilderAnnotationTemplateVars vars = new AutoBuilderAnnotationTemplateVars();\n    vars.autoBuilderType = TypeEncoder.encode(autoBuilderType.asType());\n    vars.props = annotationBuilderPropertySet(annotationType);\n    vars.pkg = TypeSimplifier.packageNameOf(autoBuilderType);\n    vars.generated =\n        generatedAnnotation(elementUtils(), processingEnv.getSourceVersion())\n            .map(annotation -> TypeEncoder.encode(annotation.asType()))\n            .orElse(\"\");\n    vars.className = TypeSimplifier.simpleNameOf(autoAnnotationClassName);\n    vars.annotationType = TypeEncoder.encode(annotationType.asType());\n    String text = vars.toText();\n    text = TypeEncoder.decode(text, processingEnv, vars.pkg, /* baseType= */ javaLangVoid);\n    text = Reformatter.fixup(text);\n    writeSourceFile(autoAnnotationClassName, text, autoBuilderType);\n    addDeferredType(autoBuilderType, autoAnnotationClassName);\n  }\n\n  private ImmutableSet<Property> annotationBuilderPropertySet(TypeElement annotationType) {\n    // Annotation methods can't have their own annotations so there's nowhere for us to discover\n    // a user @Nullable. We can only use our default @Nullable type annotation.\n    Nullables nullables = Nullables.fromMethods(processingEnv, ImmutableList.of());\n    // Translate the annotation elements into fake Property instances. We're really only interested\n    // in the name and type, so we can use them to declare a parameter of the generated\n    // @AutoAnnotation method. We'll generate a parameter for every element, even elements that\n    // don't have setters in the builder. The generated builder implementation will pass the default\n    // value from the annotation to those parameters.\n    return methodsIn(annotationType.getEnclosedElements()).stream()\n        .filter(m -> m.getParameters().isEmpty() && !m.getModifiers().contains(Modifier.STATIC))\n        .map(method -> annotationBuilderProperty(method, nullables))\n        .collect(toImmutableSet());\n  }\n\n  private static Property annotationBuilderProperty(\n      ExecutableElement annotationMethod, Nullables nullables) {\n    String name = annotationMethod.getSimpleName().toString();\n    TypeMirror type = annotationMethod.getReturnType();\n    return new Property(\n        name,\n        name,\n        TypeEncoder.encode(type),\n        new AnnotatedTypeMirror(type),\n        /* nullableAnnotation= */ Optional.empty(),\n        nullables,\n        /* getter= */ \"\",\n        /* maybeBuilderInitializer= */ Optional.empty(),\n        /* hasDefault= */ false);\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/AutoBuilderTemplateVars.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport com.google.escapevelocity.Template;\n\nclass AutoBuilderTemplateVars extends AutoValueOrBuilderTemplateVars {\n  private static final Template TEMPLATE = parsedTemplateForResource(\"autobuilder.vm\");\n\n  @Override\n  Template parsedTemplate() {\n    return TEMPLATE;\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/AutoOneOfProcessor.java",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.auto.common.MoreElements.getLocalAndInheritedMethods;\nimport static com.google.auto.value.processor.ClassNames.AUTO_ONE_OF_NAME;\nimport static java.util.stream.Collectors.toMap;\nimport static java.util.stream.Collectors.toSet;\n\nimport com.google.auto.common.AnnotationMirrors;\nimport com.google.auto.common.MoreElements;\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.service.AutoService;\nimport com.google.auto.value.processor.MissingTypes.MissingTypeException;\nimport com.google.common.collect.ImmutableBiMap;\nimport com.google.common.collect.ImmutableListMultimap;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Iterables;\nimport java.util.LinkedHashSet;\nimport java.util.Locale;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.Set;\nimport javax.annotation.processing.Processor;\nimport javax.annotation.processing.SupportedAnnotationTypes;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ElementKind;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.TypeMirror;\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessor;\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;\n\n/**\n * Javac annotation processor (compiler plugin) for {@linkplain com.google.auto.value.AutoOneOf\n * one-of} types; user code never references this class.\n *\n * @author Éamonn McManus\n * @see <a href=\"https://github.com/google/auto/tree/main/value\">AutoValue User's Guide</a>\n */\n@AutoService(Processor.class)\n@SupportedAnnotationTypes(AUTO_ONE_OF_NAME)\n@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.ISOLATING)\npublic class AutoOneOfProcessor extends AutoValueishProcessor {\n  public AutoOneOfProcessor() {\n    super(AUTO_ONE_OF_NAME, /* appliesToInterfaces= */ false);\n  }\n\n  @Override\n  boolean propertiesCanBeVoid() {\n    return true;\n  }\n\n  @Override\n  public ImmutableSet<String> getSupportedOptions() {\n    return ImmutableSet.of(Nullables.NULLABLE_OPTION);\n  }\n\n  @Override\n  void processType(TypeElement autoOneOfType) {\n    DeclaredType kindMirror = mirrorForKindType(autoOneOfType);\n\n    // We are going to classify the methods of the @AutoOneOf class into several categories.\n    // This covers the methods in the class itself and the ones it inherits from supertypes.\n    // First, the only concrete (non-abstract) methods we are interested in are overrides of\n    // Object methods (equals, hashCode, toString), which signal that we should not generate\n    // an implementation of those methods.\n    // Then, each abstract method is one of the following:\n    // (1) A property getter, like \"abstract String foo()\" or \"abstract String getFoo()\".\n    // (2) A kind getter, which is a method that returns the enum in @AutoOneOf. For\n    //     example if we have @AutoOneOf(PetKind.class), this would be a method that returns\n    //     PetKind.\n    // If there are abstract methods that don't fit any of the categories above, that is an error\n    // which we signal explicitly to avoid confusion.\n\n    ImmutableSet<ExecutableElement> methods =\n        getLocalAndInheritedMethods(\n            autoOneOfType, processingEnv.getTypeUtils(), processingEnv.getElementUtils());\n    ImmutableSet<ExecutableElement> abstractMethods = abstractMethodsIn(methods);\n    ExecutableElement kindGetter =\n        findKindGetterOrAbort(autoOneOfType, kindMirror, abstractMethods);\n    Set<ExecutableElement> otherMethods = new LinkedHashSet<>(abstractMethods);\n    otherMethods.remove(kindGetter);\n\n    ImmutableMap<ExecutableElement, AnnotatedTypeMirror> propertyMethodsAndTypes =\n        propertyMethodsIn(otherMethods, autoOneOfType);\n    ImmutableBiMap<String, ExecutableElement> properties =\n        propertyNameToMethodMap(propertyMethodsAndTypes.keySet());\n    validateMethods(autoOneOfType, abstractMethods, propertyMethodsAndTypes.keySet(), kindGetter);\n    ImmutableMap<String, String> propertyToKind =\n        propertyToKindMap(kindMirror, properties.keySet());\n\n    String subclass = generatedClassName(autoOneOfType, \"AutoOneOf_\");\n    AutoOneOfTemplateVars vars = new AutoOneOfTemplateVars();\n    vars.generatedClass = TypeSimplifier.simpleNameOf(subclass);\n    vars.propertyToKind = propertyToKind;\n    Nullables nullables = Nullables.fromMethods(processingEnv, methods);\n    defineSharedVarsForType(autoOneOfType, methods, nullables, vars);\n    defineVarsForType(autoOneOfType, vars, propertyMethodsAndTypes, kindGetter, nullables);\n\n    String text = vars.toText();\n    text = TypeEncoder.decode(text, processingEnv, vars.pkg, autoOneOfType.asType());\n    text = Reformatter.fixup(text);\n    writeSourceFile(subclass, text, autoOneOfType);\n  }\n\n  private DeclaredType mirrorForKindType(TypeElement autoOneOfType) {\n    // The annotation is guaranteed to be present by the contract of Processor#process\n    AnnotationMirror oneOfAnnotation = getAnnotationMirror(autoOneOfType, AUTO_ONE_OF_NAME).get();\n    AnnotationValue kindValue = AnnotationMirrors.getAnnotationValue(oneOfAnnotation, \"value\");\n    Object value = kindValue.getValue();\n    if (value instanceof TypeMirror) {\n      TypeMirror kindType = (TypeMirror) value;\n      switch (kindType.getKind()) {\n        case DECLARED:\n          return MoreTypes.asDeclared(kindType);\n        case ERROR:\n          throw new MissingTypeException(MoreTypes.asError(kindType));\n        default:\n          break;\n      }\n    }\n    throw new MissingTypeException(null);\n  }\n\n  private ImmutableMap<String, String> propertyToKindMap(\n      DeclaredType kindMirror, ImmutableSet<String> propertyNames) {\n    // We require a one-to-one correspondence between the property names and the enum constants.\n    // We must have transformName(propertyName) = transformName(constantName) for each one.\n    // So we build two maps, transformName(propertyName) → propertyName and\n    // transformName(constantName) → constant. The key sets of the two maps must match, and we\n    // can then join them to make propertyName → constantName.\n    TypeElement kindElement = MoreElements.asType(kindMirror.asElement());\n    Map<String, String> transformedPropertyNames =\n        propertyNames.stream().collect(toMap(this::transformName, s -> s));\n    Map<String, Element> transformedEnumConstants =\n        kindElement.getEnclosedElements().stream()\n            .filter(e -> e.getKind().equals(ElementKind.ENUM_CONSTANT))\n            .collect(toMap(e -> transformName(e.getSimpleName().toString()), e -> e));\n\n    if (transformedPropertyNames.keySet().equals(transformedEnumConstants.keySet())) {\n      ImmutableMap.Builder<String, String> mapBuilder = ImmutableMap.builder();\n      for (String transformed : transformedPropertyNames.keySet()) {\n        mapBuilder.put(\n            transformedPropertyNames.get(transformed),\n            transformedEnumConstants.get(transformed).getSimpleName().toString());\n      }\n      return mapBuilder.build();\n    }\n\n    // The names don't match. Emit errors for the differences.\n    // Properties that have no enum constant\n    transformedPropertyNames.forEach(\n        (transformed, property) -> {\n          if (!transformedEnumConstants.containsKey(transformed)) {\n            errorReporter()\n                .reportError(\n                    kindElement,\n                    \"[AutoOneOfNoEnumConstant] Enum has no constant with name corresponding to\"\n                        + \" property '%s'\",\n                    property);\n          }\n        });\n    // Enum constants that have no property\n    transformedEnumConstants.forEach(\n        (transformed, constant) -> {\n          if (!transformedPropertyNames.containsKey(transformed)) {\n            errorReporter()\n                .reportError(\n                    constant,\n                    \"[AutoOneOfBadEnumConstant] Name of enum constant '%s' does not correspond to\"\n                        + \" any property name\",\n                    constant.getSimpleName());\n          }\n        });\n    throw new AbortProcessingException();\n  }\n\n  private String transformName(String s) {\n    return s.toLowerCase(Locale.ROOT).replace(\"_\", \"\");\n  }\n\n  private ExecutableElement findKindGetterOrAbort(\n      TypeElement autoOneOfType,\n      TypeMirror kindMirror,\n      ImmutableSet<ExecutableElement> abstractMethods) {\n    Set<ExecutableElement> kindGetters =\n        abstractMethods.stream()\n            .filter(e -> sameType(kindMirror, e.getReturnType()))\n            .filter(e -> e.getParameters().isEmpty())\n            .collect(toSet());\n    switch (kindGetters.size()) {\n      case 0:\n        errorReporter()\n            .reportError(\n                autoOneOfType,\n                \"[AutoOneOfNoKindGetter] %s must have a no-arg abstract method returning %s\",\n                autoOneOfType,\n                kindMirror);\n        break;\n      case 1:\n        return Iterables.getOnlyElement(kindGetters);\n      default:\n        for (ExecutableElement getter : kindGetters) {\n          errorReporter()\n              .reportError(\n                  getter,\n                  \"[AutoOneOfTwoKindGetters] More than one abstract method returns %s\",\n                  kindMirror);\n        }\n    }\n    throw new AbortProcessingException();\n  }\n\n  private void validateMethods(\n      TypeElement type,\n      ImmutableSet<ExecutableElement> abstractMethods,\n      ImmutableSet<ExecutableElement> propertyMethods,\n      ExecutableElement kindGetter) {\n    for (ExecutableElement method : abstractMethods) {\n      if (propertyMethods.contains(method)) {\n        checkReturnType(type, method);\n      } else if (!method.equals(kindGetter)\n          && objectMethodToOverride(method) == ObjectMethod.NONE) {\n        // This could reasonably be an error, were it not for an Eclipse bug in\n        // ElementUtils.override that sometimes fails to recognize that one method overrides\n        // another, and therefore leaves us with both an abstract method and the subclass method\n        // that overrides it. This shows up in AutoValueTest.LukesBase for example.\n        // The compilation will fail anyway because the generated concrete classes won't\n        // implement this alien method.\n        errorReporter()\n            .reportWarning(\n                method,\n                \"[AutoOneOfParams] Abstract methods in @AutoOneOf classes must have no parameters\");\n      }\n    }\n    errorReporter().abortIfAnyError();\n  }\n\n  private void defineVarsForType(\n      TypeElement type,\n      AutoOneOfTemplateVars vars,\n      ImmutableMap<ExecutableElement, AnnotatedTypeMirror> propertyMethodsAndTypes,\n      ExecutableElement kindGetter,\n      Nullables nullables) {\n    vars.props =\n        propertySet(\n            propertyMethodsAndTypes,\n            /* annotatedPropertyFields= */ ImmutableListMultimap.of(),\n            /* annotatedPropertyMethods= */ ImmutableListMultimap.of(),\n            nullables);\n    vars.kindGetter = kindGetter.getSimpleName().toString();\n    vars.kindType = TypeEncoder.encode(kindGetter.getReturnType());\n    TypeElement javaIoSerializable = elementUtils().getTypeElement(\"java.io.Serializable\");\n    vars.serializable =\n        javaIoSerializable != null // just in case\n            && typeUtils().isAssignable(type.asType(), javaIoSerializable.asType());\n  }\n\n  @Override\n  Optional<String> nullableAnnotationForMethod(ExecutableElement propertyMethod) {\n    if (nullableAnnotationFor(propertyMethod, propertyMethod.getReturnType()).isPresent()) {\n      errorReporter()\n          .reportError(\n              propertyMethod, \"[AutoOneOfNullable] @AutoOneOf properties cannot be @Nullable\");\n    }\n    return Optional.empty();\n  }\n\n  private static boolean sameType(TypeMirror t1, TypeMirror t2) {\n    return MoreTypes.equivalence().equivalent(t1, t2);\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/AutoOneOfTemplateVars.java",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport com.google.common.collect.ImmutableSet;\nimport com.google.escapevelocity.Template;\nimport java.util.Map;\n\n/**\n * The variables to substitute into the autooneof.vm template.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@SuppressWarnings(\"unused\") // the fields in this class are only read via reflection\nclass AutoOneOfTemplateVars extends AutoValueishTemplateVars {\n  /**\n   * The properties defined by the parent class's abstract methods. The elements of this set are in\n   * the same order as the original abstract method declarations in the AutoOneOf class.\n   */\n  ImmutableSet<AutoOneOfProcessor.Property> props;\n\n  /** The simple name of the generated class. */\n  String generatedClass;\n\n  /** The encoded name of the \"kind\" enum class. */\n  String kindType;\n\n  /** The name of the method that gets the kind of the current {@code @AutoOneOf} instance. */\n  String kindGetter;\n\n  /** Maps property names like {@code dog} to enum constants like {@code DOG}. */\n  Map<String, String> propertyToKind;\n\n  /** True if this {@code @AutoOneOf} class is Serializable. */\n  Boolean serializable;\n\n  private static final Template TEMPLATE = parsedTemplateForResource(\"autooneof.vm\");\n\n  @Override\n  Template parsedTemplate() {\n    return TEMPLATE;\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/AutoValueBuilderProcessor.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.auto.value.processor.AutoValueishProcessor.hasAnnotationMirror;\nimport static com.google.auto.value.processor.ClassNames.AUTO_VALUE_BUILDER_NAME;\nimport static com.google.auto.value.processor.ClassNames.AUTO_VALUE_NAME;\n\nimport com.google.auto.common.SuperficialValidation;\nimport com.google.auto.service.AutoService;\nimport java.util.Set;\nimport javax.annotation.processing.AbstractProcessor;\nimport javax.annotation.processing.Processor;\nimport javax.annotation.processing.RoundEnvironment;\nimport javax.annotation.processing.SupportedAnnotationTypes;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.TypeElement;\nimport javax.tools.Diagnostic;\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessor;\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;\n\n/**\n * Annotation processor that checks that the type that {@code AutoValue.Builder} is applied to is\n * nested inside an {@code @AutoValue} class. The actual code generation for builders is done in\n * {@link AutoValueProcessor}.\n *\n * @author Éamonn McManus\n */\n@AutoService(Processor.class)\n@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.ISOLATING)\n@SupportedAnnotationTypes(AUTO_VALUE_BUILDER_NAME)\npublic class AutoValueBuilderProcessor extends AbstractProcessor {\n  @Override\n  public SourceVersion getSupportedSourceVersion() {\n    return SourceVersion.latest();\n  }\n\n  @Override\n  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n    TypeElement autoValueBuilder =\n        processingEnv.getElementUtils().getTypeElement(AUTO_VALUE_BUILDER_NAME);\n    Set<? extends Element> builderTypes = roundEnv.getElementsAnnotatedWith(autoValueBuilder);\n    if (!SuperficialValidation.validateElements(builderTypes)) {\n      return false;\n    }\n    for (Element annotatedType : builderTypes) {\n      // Double-check that the annotation is there. Sometimes the compiler gets confused in case of\n      // erroneous source code. SuperficialValidation should protect us against this but it doesn't\n      // cost anything to check again.\n      if (hasAnnotationMirror(annotatedType, AUTO_VALUE_BUILDER_NAME)) {\n        validate(\n            annotatedType,\n            \"@AutoValue.Builder can only be applied to a class or interface inside an\"\n                + \" @AutoValue class\");\n      }\n    }\n    return false;\n  }\n\n  private void validate(Element annotatedType, String errorMessage) {\n    Element container = annotatedType.getEnclosingElement();\n    if (!hasAnnotationMirror(container, AUTO_VALUE_NAME)) {\n      processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, errorMessage, annotatedType);\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/AutoValueOrBuilderTemplateVars.java",
    "content": "/*\n * Copyright 2012 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport com.google.auto.value.processor.AutoValueishProcessor.Property;\nimport com.google.auto.value.processor.PropertyBuilderClassifier.PropertyBuilder;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableMultimap;\nimport com.google.common.collect.ImmutableSet;\nimport java.util.Optional;\n\n/**\n * Variables to substitute into the autovalue.vm or builder.vm template.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@SuppressWarnings(\"unused\") // the fields in this class are only read via reflection\nabstract class AutoValueOrBuilderTemplateVars extends AutoValueishTemplateVars {\n  /**\n   * The properties defined by the parent class's abstract methods. The elements of this set are in\n   * the same order as the original abstract method declarations in the AutoValue class.\n   */\n  ImmutableSet<Property> props;\n\n  /**\n   * The simple name of the generated builder, or empty if there is no builder. This is just {@code\n   * Builder} for AutoValue, since it is nested inside the {@code AutoValue_Foo} class. But it is\n   * {@code AutoBuilder_Foo} for AutoBuilder.\n   */\n  String builderName = \"\";\n\n  /**\n   * The name of the builder type as it should appear in source code, or empty if there is no\n   * builder type. If class {@code Address} contains {@code @AutoValue.Builder} class Builder then\n   * this will typically be {@code \"Address.Builder\"}.\n   */\n  String builderTypeName = \"\";\n\n  /**\n   * The formal generic signature of the {@code AutoValue.Builder} class. This is empty, or contains\n   * type variables with optional bounds, for example {@code <K, V extends K>}.\n   */\n  String builderFormalTypes = \"\";\n\n  /**\n   * The generic signature used by the generated builder subclass for its superclass reference. This\n   * is empty, or contains only type variables with no bounds, for example {@code <K, V>}.\n   */\n  String builderActualTypes = \"\";\n\n  /** True if the builder being implemented is an interface, false if it is an abstract class. */\n  Boolean builderIsInterface = false;\n\n  /**\n   * The full spelling of any annotations to add to the generated builder subclass, or an empty list\n   * if there are none. A non-empty value might look something like\n   * {@code @`java.lang.SuppressWarnings`(\"Immutable\")}. The {@code ``} marks are explained in\n   * {@link TypeEncoder}.\n   */\n  ImmutableList<String> builderAnnotations = ImmutableList.of();\n\n  /** The builder's build method, often {@code \"build\"}. */\n  Optional<SimpleMethod> buildMethod = Optional.empty();\n\n  /** The type that will be built by the {@code build()} method of a builder. */\n  String builtType;\n\n  /**\n   * The constructor or method invocation that the {@code build()} method of a builder should use,\n   * without any parameters. This might be {@code \"new Foo\"} or {@code \"Foo.someMethod\"}.\n   */\n  String build;\n\n  /**\n   * A multimap from property names (like foo) to the corresponding setters. The same property may\n   * be set by more than one setter. For example, an ImmutableList might be set by {@code\n   * setFoo(ImmutableList<String>)} and {@code setFoo(String[])}.\n   */\n  ImmutableMultimap<String, BuilderSpec.PropertySetter> builderSetters = ImmutableMultimap.of();\n\n  /**\n   * A map from property names to information about the associated property builder. A property\n   * called foo (defined by a method foo() or getFoo()) can have a property builder called\n   * fooBuilder(). The type of foo must be a type that has an associated builder following certain\n   * conventions. Guava immutable types such as ImmutableList follow those conventions, as do many\n   * {@code @AutoValue} types.\n   */\n  ImmutableMap<String, PropertyBuilder> builderPropertyBuilders = ImmutableMap.of();\n\n  /**\n   * Properties that are required to be set. A property must be set explicitly except in the\n   * following cases:\n   *\n   * <ul>\n   *   <li>it is {@code @Nullable} (in which case it defaults to null);\n   *   <li>it has a builder initializer (for example it is {@code Optional}, which will have an\n   *       initializer of {@code Optional.empty()});\n   *   <li>it has a property-builder method (in which case it defaults to empty).\n   * </ul>\n   */\n  BuilderRequiredProperties builderRequiredProperties = BuilderRequiredProperties.EMPTY;\n\n  /**\n   * A map from property names to information about the associated property getter. A property\n   * called foo (defined by a method foo() or getFoo()) can have a property getter method with the\n   * same name (foo() or getFoo()) and either the same return type or an Optional (or OptionalInt,\n   * etc) wrapping it.\n   */\n  ImmutableMap<String, BuilderSpec.PropertyGetter> builderGetters = ImmutableMap.of();\n\n  /**\n   * True if the generated builder should have a second constructor with a parameter of the built\n   * type. The constructor produces a new builder that starts off with the values from the\n   * parameter.\n   */\n  Boolean toBuilderConstructor;\n\n  /**\n   * Any {@code toBuilder()} methods, that is methods that return the builder type. AutoBuilder does\n   * not support this, but it's included in these shared variables to simplify the template.\n   */\n  ImmutableList<SimpleMethod> toBuilderMethods;\n\n  /**\n   * Whether to include identifiers in strings in the generated code. If false, exception messages\n   * will not mention properties by name, and {@code toString()} will include neither property names\n   * nor the name of the {@code @AutoValue} class.\n   */\n  Boolean identifiers;\n\n  /**\n   * True if the generated class should be final (there are no extensions that will generate\n   * subclasses)\n   */\n  Boolean isFinal = false;\n\n  /**\n   * The modifiers (for example {@code final} or {@code abstract}) for the generated builder\n   * subclass, followed by a space if they are not empty.\n   */\n  String builderClassModifiers = \"\";\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/AutoValueProcessor.java",
    "content": "/*\n * Copyright 2012 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.auto.common.MoreElements.getLocalAndInheritedMethods;\nimport static com.google.auto.value.processor.ClassNames.AUTO_VALUE_NAME;\nimport static com.google.common.base.Preconditions.checkState;\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static com.google.common.collect.Sets.difference;\nimport static com.google.common.collect.Sets.intersection;\nimport static java.util.Comparator.naturalOrder;\nimport static java.util.stream.Collectors.joining;\n\nimport com.google.auto.service.AutoService;\nimport com.google.auto.value.extension.AutoValueExtension;\nimport com.google.common.annotations.VisibleForTesting;\nimport com.google.common.base.Strings;\nimport com.google.common.base.Throwables;\nimport com.google.common.collect.ImmutableBiMap;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableListMultimap;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport java.lang.annotation.Annotation;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Optional;\nimport java.util.ServiceConfigurationError;\nimport java.util.Set;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.annotation.processing.Processor;\nimport javax.annotation.processing.SupportedAnnotationTypes;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessor;\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;\n\n/**\n * Javac annotation processor (compiler plugin) for value types; user code never references this\n * class.\n *\n * @see <a href=\"https://github.com/google/auto/tree/main/value\">AutoValue User's Guide</a>\n * @author Éamonn McManus\n */\n@AutoService(Processor.class)\n@SupportedAnnotationTypes(AUTO_VALUE_NAME)\n@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.DYNAMIC)\npublic class AutoValueProcessor extends AutoValueishProcessor {\n  static final String OMIT_IDENTIFIERS_OPTION = \"com.google.auto.value.OmitIdentifiers\";\n\n  // We moved MemoizeExtension to a different package, which had an unexpected effect:\n  // now if an old version of AutoValue is in the class path, ServiceLoader can pick up both the\n  // old and the new versions of MemoizeExtension. So we exclude the old version if we see it.\n  // The new version will be bundled with this processor so we should always find it.\n  private static final String OLD_MEMOIZE_EXTENSION =\n      \"com.google.auto.value.extension.memoized.MemoizeExtension\";\n\n  public AutoValueProcessor() {\n    this(AutoValueProcessor.class.getClassLoader());\n  }\n\n  @VisibleForTesting\n  AutoValueProcessor(ClassLoader loaderForExtensions) {\n    this(ImmutableList.of(), loaderForExtensions);\n  }\n\n  @VisibleForTesting\n  public AutoValueProcessor(Iterable<? extends AutoValueExtension> testExtensions) {\n    this(testExtensions, null);\n  }\n\n  private AutoValueProcessor(\n      Iterable<? extends AutoValueExtension> testExtensions, ClassLoader loaderForExtensions) {\n    super(AUTO_VALUE_NAME, /* appliesToInterfaces= */ false);\n    this.extensions = ImmutableList.copyOf(testExtensions);\n    this.loaderForExtensions = loaderForExtensions;\n  }\n\n  // Depending on how this AutoValueProcessor was constructed, we might already have a list of\n  // extensions when init() is run, or, if `loaderForExtensions` is not null, it is a ClassLoader\n  // that will be used to get the list using the ServiceLoader API.\n  private ImmutableList<AutoValueExtension> extensions;\n  private final ClassLoader loaderForExtensions;\n\n  @VisibleForTesting\n  static ImmutableList<AutoValueExtension> extensionsFromLoader(ClassLoader loader) {\n    return SimpleServiceLoader.load(AutoValueExtension.class, loader).stream()\n        .filter(ext -> !ext.getClass().getName().equals(OLD_MEMOIZE_EXTENSION))\n        .collect(toImmutableList());\n  }\n\n  @Override\n  public synchronized void init(ProcessingEnvironment processingEnv) {\n    super.init(processingEnv);\n\n    if (loaderForExtensions != null) {\n      checkState(extensions.isEmpty());\n      try {\n        extensions = extensionsFromLoader(loaderForExtensions);\n      } catch (RuntimeException | Error e) {\n        String explain =\n            (e instanceof ServiceConfigurationError)\n                ? \" This may be due to a corrupt jar file in the compiler's classpath.\"\n                : \"\";\n        errorReporter()\n            .reportWarning(\n                null,\n                \"[AutoValueExtensionsException] An exception occurred while looking for AutoValue\"\n                    + \" extensions. No extensions will function.%s\\n%s\",\n                explain,\n                Throwables.getStackTraceAsString(e));\n        extensions = ImmutableList.of();\n      }\n    }\n  }\n\n  @Override\n  public ImmutableSet<String> getSupportedOptions() {\n    ImmutableSet.Builder<String> builder = ImmutableSet.builder();\n    AutoValueExtension.IncrementalExtensionType incrementalType =\n        extensions.stream()\n            .map(e -> e.incrementalType(processingEnv))\n            .min(naturalOrder())\n            .orElse(AutoValueExtension.IncrementalExtensionType.ISOLATING);\n    builder\n        .add(OMIT_IDENTIFIERS_OPTION)\n        .add(Nullables.NULLABLE_OPTION)\n        .addAll(optionsFor(incrementalType));\n    for (AutoValueExtension extension : extensions) {\n      builder.addAll(extension.getSupportedOptions());\n    }\n    return builder.build();\n  }\n\n  private static ImmutableSet<String> optionsFor(\n      AutoValueExtension.IncrementalExtensionType incrementalType) {\n    switch (incrementalType) {\n      case ISOLATING:\n        return ImmutableSet.of(IncrementalAnnotationProcessorType.ISOLATING.getProcessorOption());\n      case AGGREGATING:\n        return ImmutableSet.of(IncrementalAnnotationProcessorType.AGGREGATING.getProcessorOption());\n      case UNKNOWN:\n        return ImmutableSet.of();\n    }\n    throw new AssertionError(incrementalType);\n  }\n\n  static String generatedSubclassName(TypeElement type, int depth) {\n    return generatedClassName(type, Strings.repeat(\"$\", depth) + \"AutoValue_\");\n  }\n\n  @Override\n  void processType(TypeElement type) {\n    if (ancestorIsAutoValue(type)) {\n      errorReporter()\n          .abortWithError(type, \"[AutoValueExtend] One @AutoValue class may not extend another\");\n    }\n    if (implementsAnnotation(type)) {\n      errorReporter()\n          .abortWithError(\n              type,\n              \"[AutoValueImplAnnotation] @AutoValue may not be used to implement an annotation\"\n                  + \" interface; try using @AutoAnnotation or @AutoBuilder instead\");\n    }\n\n    // We are going to classify the methods of the @AutoValue class into several categories.\n    // This covers the methods in the class itself and the ones it inherits from supertypes.\n    // First, the only concrete (non-abstract) methods we are interested in are overrides of\n    // Object methods (equals, hashCode, toString), which signal that we should not generate\n    // an implementation of those methods.\n    // Then, each abstract method is one of the following:\n    // (1) A property getter, like \"abstract String foo()\" or \"abstract String getFoo()\".\n    // (2) A toBuilder() method, which is any abstract no-arg method returning the Builder for\n    //     this @AutoValue class.\n    // (3) An abstract method that will be consumed by an extension, such as\n    //     Parcelable.describeContents() or Parcelable.writeToParcel(Parcel, int).\n    // The describeContents() example shows a quirk here: initially we will identify it as a\n    // property, which means that we need to reconstruct the list of properties after allowing\n    // extensions to consume abstract methods.\n    // If there are abstract methods that don't fit any of the categories above, that is an error\n    // which we signal explicitly to avoid confusion.\n\n    ImmutableSet<ExecutableElement> methods =\n        getLocalAndInheritedMethods(\n            type, processingEnv.getTypeUtils(), processingEnv.getElementUtils());\n    ImmutableSet<ExecutableElement> abstractMethods = abstractMethodsIn(methods);\n\n    BuilderSpec builderSpec = new BuilderSpec(type, processingEnv, errorReporter());\n    Optional<BuilderSpec.Builder> builder = builderSpec.getBuilder();\n    ImmutableSet<ExecutableElement> toBuilderMethods;\n    ImmutableSet<ExecutableElement> builderAbstractMethods;\n    if (builder.isPresent()) {\n      toBuilderMethods = builder.get().toBuilderMethods(typeUtils(), type, abstractMethods);\n      builderAbstractMethods = builder.get().builderAbstractMethods();\n    } else {\n      toBuilderMethods = ImmutableSet.of();\n      builderAbstractMethods = ImmutableSet.of();\n    }\n\n    ImmutableMap<ExecutableElement, AnnotatedTypeMirror> propertyMethodsAndTypes =\n        propertyMethodsIn(immutableSetDifference(abstractMethods, toBuilderMethods), type);\n    ImmutableMap<String, ExecutableElement> properties =\n        propertyNameToMethodMap(propertyMethodsAndTypes.keySet());\n\n    ExtensionContext context =\n        new ExtensionContext(\n            this,\n            processingEnv,\n            type,\n            properties,\n            propertyMethodsAndTypes,\n            abstractMethods,\n            builderAbstractMethods);\n    ImmutableList<AutoValueExtension> applicableExtensions = applicableExtensions(type, context);\n    ImmutableSet<ExecutableElement> consumedMethods =\n        methodsConsumedByExtensions(\n            type, applicableExtensions, context, abstractMethods, properties);\n    ImmutableSet<ExecutableElement> consumedBuilderMethods =\n        builderMethodsConsumedByExtensions(\n            type, applicableExtensions, context, builderAbstractMethods);\n\n    if (!consumedMethods.isEmpty()) {\n      ImmutableSet<ExecutableElement> allAbstractMethods = abstractMethods;\n      abstractMethods = immutableSetDifference(abstractMethods, consumedMethods);\n      toBuilderMethods = immutableSetDifference(toBuilderMethods, consumedMethods);\n      propertyMethodsAndTypes =\n          propertyMethodsIn(immutableSetDifference(abstractMethods, toBuilderMethods), type);\n      properties = propertyNameToMethodMap(propertyMethodsAndTypes.keySet());\n      context =\n          new ExtensionContext(\n              this,\n              processingEnv,\n              type,\n              properties,\n              propertyMethodsAndTypes,\n              allAbstractMethods,\n              builderAbstractMethods);\n    }\n\n    ImmutableSet<ExecutableElement> propertyMethods = propertyMethodsAndTypes.keySet();\n    boolean extensionsPresent = !applicableExtensions.isEmpty();\n    validateMethods(type, abstractMethods, toBuilderMethods, propertyMethods, extensionsPresent);\n\n    String finalSubclass = TypeSimplifier.simpleNameOf(generatedSubclassName(type, 0));\n    AutoValueTemplateVars vars = new AutoValueTemplateVars();\n    vars.identifiers = !processingEnv.getOptions().containsKey(OMIT_IDENTIFIERS_OPTION);\n    Nullables nullables = Nullables.fromMethods(processingEnv, methods);\n    defineSharedVarsForType(type, methods, nullables, vars);\n    defineVarsForType(\n        type,\n        vars,\n        toBuilderMethods,\n        propertyMethodsAndTypes,\n        builder,\n        nullables,\n        consumedBuilderMethods);\n    vars.builtType = vars.origClass + vars.actualTypes;\n    vars.build = \"new \" + finalSubclass + vars.actualTypes;\n\n    // If we've encountered problems then we might end up invoking extensions with inconsistent\n    // state. Anyway we probably don't want to generate code which is likely to provoke further\n    // compile errors to add to the ones we've already seen.\n    errorReporter().abortIfAnyError();\n\n    GwtCompatibility gwtCompatibility = new GwtCompatibility(type);\n    vars.gwtCompatibleAnnotation = gwtCompatibility.gwtCompatibleAnnotationString();\n\n    builder.ifPresent(context::setBuilderContext);\n    int subclassDepth = writeExtensions(type, context, applicableExtensions);\n    String subclass = generatedSubclassName(type, subclassDepth);\n    vars.subclass = TypeSimplifier.simpleNameOf(subclass);\n    vars.finalSubclass = finalSubclass;\n    vars.isFinal = (subclassDepth == 0);\n    vars.modifiers = vars.isFinal ? \"final \" : \"abstract \";\n    vars.builderClassModifiers =\n        consumedBuilderMethods.isEmpty()\n            ? vars.isFinal ? \"static final \" : \"static \"\n            : \"abstract static \";\n\n    String text = vars.toText();\n    text = TypeEncoder.decode(text, processingEnv, vars.pkg, type.asType());\n    text = Reformatter.fixup(text);\n    writeSourceFile(subclass, text, type);\n    GwtSerialization gwtSerialization = new GwtSerialization(gwtCompatibility, processingEnv, type);\n    gwtSerialization.maybeWriteGwtSerializer(vars, finalSubclass);\n  }\n\n  // Invokes each of the given extensions to generate its subclass, and returns the number of\n  // hierarchy classes that extensions generated. This number is then the number of $ characters\n  // that should precede the name of the AutoValue implementation class.\n  // Assume the @AutoValue class is com.example.Foo.Bar. Then if there are no\n  // extensions the returned value will be 0, so the AutoValue implementation will be\n  // com.example.AutoValue_Foo_Bar. If there is one extension, it will be asked to\n  // generate AutoValue_Foo_Bar with parent $AutoValue_Foo_Bar. If it does so (returns\n  // non-null) then the returned value will be 1, so the AutoValue implementation will be\n  // com.example.$AutoValue_Foo_Bar. Otherwise, the returned value will still be 0. Likewise,\n  // if there is a second extension and both extensions return non-null, the first one will\n  // generate AutoValue_Foo_Bar with parent $AutoValue_Foo_Bar, the second will generate\n  // $AutoValue_Foo_Bar with parent $$AutoValue_Foo_Bar, and the returned value will be 2 for\n  // com.example.$$AutoValue_Foo_Bar.\n  private int writeExtensions(\n      TypeElement type,\n      ExtensionContext context,\n      ImmutableList<AutoValueExtension> applicableExtensions) {\n    int writtenSoFar = 0;\n    for (AutoValueExtension extension : applicableExtensions) {\n      String parentFqName = generatedSubclassName(type, writtenSoFar + 1);\n      String parentSimpleName = TypeSimplifier.simpleNameOf(parentFqName);\n      String classFqName = generatedSubclassName(type, writtenSoFar);\n      String classSimpleName = TypeSimplifier.simpleNameOf(classFqName);\n      boolean isFinal = (writtenSoFar == 0);\n      String source = extension.generateClass(context, classSimpleName, parentSimpleName, isFinal);\n      if (source != null) {\n        source = Reformatter.fixup(source);\n        writeSourceFile(classFqName, source, type);\n        writtenSoFar++;\n      }\n    }\n    return writtenSoFar;\n  }\n\n  private ImmutableList<AutoValueExtension> applicableExtensions(\n      TypeElement type, ExtensionContext context) {\n    List<AutoValueExtension> applicableExtensions = new ArrayList<>();\n    List<AutoValueExtension> finalExtensions = new ArrayList<>();\n    for (AutoValueExtension extension : extensions) {\n      if (extension.applicable(context)) {\n        if (extension.mustBeFinal(context)) {\n          finalExtensions.add(extension);\n        } else {\n          applicableExtensions.add(extension);\n        }\n      }\n    }\n    switch (finalExtensions.size()) {\n      case 0:\n        break;\n      case 1:\n        applicableExtensions.add(0, finalExtensions.get(0));\n        break;\n      default:\n        errorReporter()\n            .reportError(\n                type,\n                \"[AutoValueMultiFinal] More than one extension wants to generate the final class:\"\n                    + \" %s\",\n                finalExtensions.stream().map(this::extensionName).collect(joining(\", \")));\n        break;\n    }\n    return ImmutableList.copyOf(applicableExtensions);\n  }\n\n  private ImmutableSet<ExecutableElement> methodsConsumedByExtensions(\n      TypeElement type,\n      ImmutableList<AutoValueExtension> applicableExtensions,\n      ExtensionContext context,\n      ImmutableSet<ExecutableElement> abstractMethods,\n      ImmutableMap<String, ExecutableElement> properties) {\n    Set<ExecutableElement> consumed = new HashSet<>();\n    for (AutoValueExtension extension : applicableExtensions) {\n      Set<ExecutableElement> consumedHere = new HashSet<>();\n      for (String consumedProperty : extension.consumeProperties(context)) {\n        ExecutableElement propertyMethod = properties.get(consumedProperty);\n        if (propertyMethod == null) {\n          errorReporter()\n              .reportError(\n                  type,\n                  \"[AutoValueConsumeNonexist] Extension %s wants to consume a property that does\"\n                      + \" not exist: %s\",\n                  extensionName(extension),\n                  consumedProperty);\n        } else {\n          consumedHere.add(propertyMethod);\n        }\n      }\n      for (ExecutableElement consumedMethod : extension.consumeMethods(context)) {\n        if (!abstractMethods.contains(consumedMethod)) {\n          errorReporter()\n              .reportError(\n                  type,\n                  \"[AutoValueConsumeNotAbstract] Extension %s wants to consume a method that is\"\n                      + \" not one of the abstract methods in this class: %s\",\n                  extensionName(extension),\n                  consumedMethod);\n        } else {\n          consumedHere.add(consumedMethod);\n        }\n      }\n      for (ExecutableElement repeat : intersection(consumed, consumedHere)) {\n        errorReporter()\n            .reportError(\n                repeat,\n                \"[AutoValueMultiConsume] Extension %s wants to consume a method that was already\"\n                    + \" consumed by another extension\",\n                extensionName(extension));\n      }\n      consumed.addAll(consumedHere);\n    }\n    return ImmutableSet.copyOf(consumed);\n  }\n\n  private ImmutableSet<ExecutableElement> builderMethodsConsumedByExtensions(\n      TypeElement type,\n      ImmutableList<AutoValueExtension> applicableExtensions,\n      ExtensionContext context,\n      ImmutableSet<ExecutableElement> builderAbstractMethods) {\n    Set<ExecutableElement> consumed = new HashSet<>();\n    for (AutoValueExtension extension : applicableExtensions) {\n      Set<ExecutableElement> consumedHere = new HashSet<>();\n      for (ExecutableElement consumedMethod : extension.consumeBuilderMethods(context)) {\n        if (!builderAbstractMethods.contains(consumedMethod)) {\n          errorReporter()\n              .reportError(\n                  type,\n                  \"[AutoValueBuilderConsumeNotAbstract] Extension %s wants to consume a method that\"\n                      + \" is not one of the abstract methods in this class: %s\",\n                  extensionName(extension),\n                  consumedMethod);\n        } else {\n          consumedHere.add(consumedMethod);\n        }\n      }\n      for (ExecutableElement repeat : intersection(consumed, consumedHere)) {\n        errorReporter()\n            .reportError(\n                repeat,\n                \"[AutoValueBuilderConsumeNotAbstract] Extension %s wants to consume a method that\"\n                    + \" was already consumed by another extension\",\n                extensionName(extension));\n      }\n      consumed.addAll(consumedHere);\n    }\n    return ImmutableSet.copyOf(consumed);\n  }\n\n  private void validateMethods(\n      TypeElement type,\n      ImmutableSet<ExecutableElement> abstractMethods,\n      ImmutableSet<ExecutableElement> toBuilderMethods,\n      ImmutableSet<ExecutableElement> propertyMethods,\n      boolean extensionsPresent) {\n    for (ExecutableElement method : abstractMethods) {\n      if (propertyMethods.contains(method)) {\n        checkReturnType(type, method);\n      } else if (!toBuilderMethods.contains(method)\n          && objectMethodToOverride(method) == ObjectMethod.NONE) {\n        // This could reasonably be an error, were it not for an Eclipse bug in\n        // ElementUtils.override that sometimes fails to recognize that one method overrides\n        // another, and therefore leaves us with both an abstract method and the subclass method\n        // that overrides it. This shows up in AutoValueTest.LukesBase for example.\n        String extensionMessage = extensionsPresent ? \", and no extension consumed it\" : \"\";\n        errorReporter()\n            .reportWarning(\n                method,\n                \"[AutoValueBuilderWhat] Abstract method is neither a property getter nor a Builder\"\n                    + \" converter%s\",\n                extensionMessage);\n      }\n    }\n    errorReporter().abortIfAnyError();\n  }\n\n  private String extensionName(AutoValueExtension extension) {\n    return extension.getClass().getName();\n  }\n\n  private void defineVarsForType(\n      TypeElement type,\n      AutoValueTemplateVars vars,\n      ImmutableSet<ExecutableElement> toBuilderMethods,\n      ImmutableMap<ExecutableElement, AnnotatedTypeMirror> propertyMethodsAndTypes,\n      Optional<BuilderSpec.Builder> maybeBuilder,\n      Nullables nullables,\n      ImmutableSet<ExecutableElement> consumedBuilderAbstractMethods) {\n    ImmutableSet<ExecutableElement> propertyMethods = propertyMethodsAndTypes.keySet();\n    vars.toBuilderMethods =\n        toBuilderMethods.stream().map(SimpleMethod::new).collect(toImmutableList());\n    vars.toBuilderConstructor = !vars.toBuilderMethods.isEmpty();\n    ImmutableListMultimap<ExecutableElement, AnnotationMirror> annotatedPropertyFields =\n        propertyFieldAnnotationMap(type, propertyMethods);\n    ImmutableListMultimap<ExecutableElement, AnnotationMirror> annotatedPropertyMethods =\n        propertyMethodAnnotationMap(type, propertyMethods);\n    vars.props =\n        propertySet(\n            propertyMethodsAndTypes, annotatedPropertyFields, annotatedPropertyMethods, nullables);\n    // Check for @AutoValue.Builder and add appropriate variables if it is present.\n    maybeBuilder.ifPresent(\n        builder -> {\n          ImmutableBiMap<ExecutableElement, String> methodToPropertyName =\n              propertyNameToMethodMap(propertyMethods).inverse();\n          builder.defineVarsForAutoValue(\n              vars, methodToPropertyName, nullables, consumedBuilderAbstractMethods);\n          vars.builderName = \"Builder\";\n          vars.builderAnnotations = copiedClassAnnotations(builder.builderType());\n        });\n  }\n\n  @Override\n  Optional<String> nullableAnnotationForMethod(ExecutableElement propertyMethod) {\n    return nullableAnnotationFor(propertyMethod, propertyMethod.getReturnType());\n  }\n\n  static ImmutableSet<ExecutableElement> prefixedGettersIn(Iterable<ExecutableElement> methods) {\n    ImmutableSet.Builder<ExecutableElement> getters = ImmutableSet.builder();\n    for (ExecutableElement method : methods) {\n      String name = method.getSimpleName().toString();\n      // TODO(emcmanus): decide whether getfoo() (without a capital) is a getter. Currently it is.\n      boolean get = name.startsWith(\"get\") && !name.equals(\"get\");\n      boolean is =\n          name.startsWith(\"is\")\n              && !name.equals(\"is\")\n              && method.getReturnType().getKind() == TypeKind.BOOLEAN;\n      if (get || is) {\n        getters.add(method);\n      }\n    }\n    return getters.build();\n  }\n\n  private boolean ancestorIsAutoValue(TypeElement type) {\n    while (true) {\n      TypeMirror parentMirror = type.getSuperclass();\n      if (parentMirror.getKind() == TypeKind.NONE) {\n        return false;\n      }\n      TypeElement parentElement = (TypeElement) typeUtils().asElement(parentMirror);\n      if (hasAnnotationMirror(parentElement, AUTO_VALUE_NAME)) {\n        return true;\n      }\n      type = parentElement;\n    }\n  }\n\n  private boolean implementsAnnotation(TypeElement type) {\n    return typeUtils().isAssignable(type.asType(), getTypeMirror(Annotation.class));\n  }\n\n  private TypeMirror getTypeMirror(Class<?> c) {\n    return processingEnv.getElementUtils().getTypeElement(c.getName()).asType();\n  }\n\n  private static <E> ImmutableSet<E> immutableSetDifference(ImmutableSet<E> a, ImmutableSet<E> b) {\n    if (Collections.disjoint(a, b)) {\n      return a;\n    } else {\n      return difference(a, b).immutableCopy();\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/AutoValueTemplateVars.java",
    "content": "/*\n * Copyright 2012 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport com.google.escapevelocity.Template;\n\n/**\n * The variables to substitute into the autovalue.vm template.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@SuppressWarnings(\"unused\") // the fields in this class are only read via reflection\nclass AutoValueTemplateVars extends AutoValueOrBuilderTemplateVars {\n\n  /**\n   * The encoding of the {@code @GwtCompatible} annotation to add to this class, or an empty string\n   * if there is none. A non-empty value will look something like {@code\n   * \"@`com.google.common.annotations.GwtCompatible`(serializable = true)\"}, where the {@code ``}\n   * represent the encoding used by {@link TypeEncoder}.\n   */\n  String gwtCompatibleAnnotation;\n\n  /** The simple name of the generated subclass. */\n  String subclass;\n\n  /**\n   * The simple name of the final subclass. This is the same as {@link #subclass} unless there are\n   * extensions. If there are extensions, then {@link #subclass} might be something like {@code\n   * $$AutoValue_Foo} while {@code finalSubclass} will be {@code AutoValue_Foo}.\n   */\n  String finalSubclass;\n\n  /**\n   * The modifiers (for example {@code final} or {@code abstract}) for the generated subclass,\n   * followed by a space if they are not empty.\n   */\n  String modifiers;\n\n  private static final Template TEMPLATE = parsedTemplateForResource(\"autovalue.vm\");\n\n  @Override\n  Template parsedTemplate() {\n    return TEMPLATE;\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/AutoValueishProcessor.java",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.auto.common.AnnotationMirrors.getAnnotationValue;\nimport static com.google.auto.common.GeneratedAnnotations.generatedAnnotation;\nimport static com.google.auto.common.MoreElements.asType;\nimport static com.google.auto.common.MoreElements.getPackage;\nimport static com.google.auto.common.MoreElements.isAnnotationPresent;\nimport static com.google.auto.value.processor.ClassNames.AUTO_VALUE_PACKAGE_NAME;\nimport static com.google.auto.value.processor.ClassNames.COPY_ANNOTATIONS_NAME;\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static com.google.common.collect.ImmutableMap.toImmutableMap;\nimport static com.google.common.collect.ImmutableSet.toImmutableSet;\nimport static com.google.common.collect.Iterables.getOnlyElement;\nimport static com.google.common.collect.Sets.union;\nimport static java.util.stream.Collectors.joining;\nimport static java.util.stream.Collectors.toCollection;\nimport static java.util.stream.Collectors.toSet;\nimport static javax.lang.model.util.ElementFilter.constructorsIn;\n\nimport com.google.auto.common.MoreElements;\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.common.Visibility;\nimport com.google.auto.value.processor.MissingTypes.MissingTypeException;\nimport com.google.common.base.Throwables;\nimport com.google.common.collect.ImmutableBiMap;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableListMultimap;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport java.io.IOException;\nimport java.io.Serializable;\nimport java.io.Writer;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Inherited;\nimport java.lang.annotation.Target;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.EnumMap;\nimport java.util.HashSet;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.OptionalInt;\nimport java.util.Set;\nimport java.util.function.Predicate;\nimport java.util.stream.IntStream;\nimport javax.annotation.processing.AbstractProcessor;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.annotation.processing.RoundEnvironment;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ElementKind;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.Modifier;\nimport javax.lang.model.element.Name;\nimport javax.lang.model.element.QualifiedNameable;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.TypeParameterElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.type.TypeVariable;\nimport javax.lang.model.util.ElementFilter;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.SimpleAnnotationValueVisitor8;\nimport javax.lang.model.util.Types;\nimport javax.tools.Diagnostic;\nimport javax.tools.JavaFileObject;\n\n/**\n * Shared code between {@link AutoValueProcessor}, {@link AutoOneOfProcessor}, and {@link\n * AutoBuilderProcessor}.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\nabstract class AutoValueishProcessor extends AbstractProcessor {\n  private final String annotationClassName;\n  private final boolean appliesToInterfaces;\n\n  /**\n   * Qualified names of {@code @AutoValue} (etc) classes that we attempted to process but had to\n   * abandon because we needed other types that they referenced and those other types were missing.\n   * The corresponding value tells the name of the missing type, if known, or is empty otherwise.\n   */\n  private final Map<String, String> deferredTypeNames = new LinkedHashMap<>();\n\n  AutoValueishProcessor(String annotationClassName, boolean appliesToInterfaces) {\n    this.annotationClassName = annotationClassName;\n    this.appliesToInterfaces = appliesToInterfaces;\n  }\n\n  /** The annotation we are processing, for example {@code AutoValue} or {@code AutoBuilder}. */\n  private TypeElement annotationType;\n\n  /** The simple name of {@link #annotationType}. */\n  private String simpleAnnotationName;\n\n  private ErrorReporter errorReporter;\n\n  @Override\n  public synchronized void init(ProcessingEnvironment processingEnv) {\n    super.init(processingEnv);\n    errorReporter = new ErrorReporter(processingEnv);\n    annotationType = elementUtils().getTypeElement(annotationClassName);\n    if (annotationType != null) {\n      simpleAnnotationName = annotationType.getSimpleName().toString();\n    }\n  }\n\n  final ErrorReporter errorReporter() {\n    return errorReporter;\n  }\n\n  final Types typeUtils() {\n    return processingEnv.getTypeUtils();\n  }\n\n  final Elements elementUtils() {\n    return processingEnv.getElementUtils();\n  }\n\n  /**\n   * Qualified names of {@code @AutoValue} (etc) classes that we attempted to process but had to\n   * abandon because we needed other types that they referenced and those other types were missing.\n   * This is used by tests.\n   */\n  final ImmutableList<String> deferredTypeNames() {\n    return ImmutableList.copyOf(deferredTypeNames.keySet());\n  }\n\n  @Override\n  public final SourceVersion getSupportedSourceVersion() {\n    return SourceVersion.latestSupported();\n  }\n\n  /**\n   * A property of an {@code @AutoValue} (etc) class, defined by one of its abstract methods. An\n   * instance of this class is made available to the Velocity template engine for each property. The\n   * public methods of this class define JavaBeans-style properties that are accessible from\n   * templates. For example {@link #getType()} means we can write {@code $p.type} for a Velocity\n   * variable {@code $p} that is a {@code Property}.\n   */\n  public static class Property {\n    private final String name;\n    private final String identifier;\n    private final String type;\n    private final AnnotatedTypeMirror annotatedType;\n    private final Optional<String> nullableAnnotation;\n    private final ImmutableList<AnnotationMirror> availableNullableTypeAnnotations; // 0 or 1\n    private final Optionalish optional;\n    private final String getter;\n    private final String builderInitializer; // empty, or with initial ` = `.\n    private final boolean hasDefault;\n\n    Property(\n        String name,\n        String identifier,\n        String type,\n        AnnotatedTypeMirror annotatedType,\n        Optional<String> nullableAnnotation,\n        Nullables nullables,\n        String getter,\n        Optional<String> maybeBuilderInitializer,\n        boolean hasDefault) {\n      this.name = name;\n      this.identifier = identifier;\n      this.type = type;\n      this.annotatedType = annotatedType;\n      this.nullableAnnotation = nullableAnnotation;\n      this.availableNullableTypeAnnotations = nullables.nullableTypeAnnotations();\n      this.optional = Optionalish.createIfOptional(annotatedType.getType());\n      this.builderInitializer =\n          maybeBuilderInitializer.isPresent()\n              ? \" = \" + maybeBuilderInitializer.get()\n              : builderInitializer(annotatedType, nullableAnnotation);\n      this.getter = getter;\n      this.hasDefault = hasDefault;\n    }\n\n    /**\n     * Returns the appropriate initializer for a builder property. The caller of the {@code\n     * Property} constructor may have supplied an initializer, but otherwise we supply one only if\n     * this property is an {@code Optional} and is not {@code @Nullable}. In that case the\n     * initializer sets it to {@code Optional.empty()}.\n     */\n    private static String builderInitializer(\n        AnnotatedTypeMirror annotatedType, Optional<String> nullableAnnotation) {\n      if (nullableAnnotation.isPresent()) {\n        return \"\";\n      }\n      Optionalish optional = Optionalish.createIfOptional(annotatedType.getType());\n      if (optional == null) {\n        return \"\";\n      }\n      return \" = \" + optional.getEmpty();\n    }\n\n    /**\n     * Returns the appropriate type for a builder field that will eventually be assigned to this\n     * property. This is the same as the final property type, except that it may have an additional\n     * {@code @Nullable} annotation. Some builder fields start off null and then acquire a value\n     * when the corresponding setter is called. Builder fields should have an extra\n     * {@code @Nullable} if all of the following conditions are met:\n     *\n     * <ul>\n     *   <li>the property is not primitive;\n     *   <li>the property type does not already have a {@code @Nullable} annotation;\n     *   <li>there is no explicit initializer (for example {@code Optional} properties start off as\n     *       {@code Optional.empty()});\n     *   <li>we have found a {@code @Nullable} type annotation that can be applied.\n     * </ul>\n     */\n    public String getBuilderFieldType() {\n      if (annotatedType.getType().getKind().isPrimitive()\n          || nullableAnnotation.isPresent()\n          || !builderInitializer.isEmpty()\n          || availableNullableTypeAnnotations.isEmpty()) {\n        return type;\n      }\n      return TypeEncoder.encodeWithAnnotations(annotatedType, availableNullableTypeAnnotations);\n    }\n\n    /**\n     * Returns the name of the property as it should be used when declaring identifiers (fields and\n     * parameters). If the original getter method was {@code foo()} then this will be {@code foo}.\n     * If it was {@code getFoo()} then it will be {@code foo}. If it was {@code getPackage()} then\n     * it will be something like {@code package0}, since {@code package} is a reserved word.\n     */\n    @Override\n    public String toString() {\n      return identifier;\n    }\n\n    /**\n     * Returns the name of the property as it should be used in strings visible to users. This is\n     * usually the same as {@code toString()}, except that if we had to use an identifier like\n     * \"package0\" because \"package\" is a reserved word, the name here will be the original\n     * \"package\".\n     */\n    public String getName() {\n      return name;\n    }\n\n    TypeMirror getTypeMirror() {\n      return annotatedType.getType();\n    }\n\n    public String getType() {\n      return type;\n    }\n\n    public TypeKind getKind() {\n      return annotatedType.getType().getKind();\n    }\n\n    /**\n     * Returns an {@link Optionalish} representing the kind of Optional that this property's type\n     * is, or null if the type is not an Optional of any kind.\n     */\n    public Optionalish getOptional() {\n      return optional;\n    }\n\n    /**\n     * Returns a string to be used as an initializer for a builder field for this property,\n     * including the leading {@code =}, or an empty string if there is no explicit initializer.\n     */\n    public String getBuilderInitializer() {\n      return builderInitializer;\n    }\n\n    /**\n     * Returns the string to use as a method annotation to indicate the nullability of this\n     * property. It is either the empty string, if the property is not nullable, or an annotation\n     * string with a trailing space, such as {@code \"@`javax.annotation.Nullable` \"}, where the\n     * {@code ``} is the encoding used by {@link TypeEncoder}. If the property is nullable by virtue\n     * of its <i>type</i> rather than its method being {@code @Nullable}, this method returns the\n     * empty string, because the {@code @Nullable} will appear when the type is spelled out. In this\n     * case, {@link #nullableAnnotation} is present but empty.\n     */\n    public final String getNullableAnnotation() {\n      return nullableAnnotation.orElse(\"\");\n    }\n\n    public boolean isNullable() {\n      return nullableAnnotation.isPresent();\n    }\n\n    /**\n     * Returns the name of the getter method for this property as defined by the {@code @AutoValue}\n     * or {@code @AutoBuilder} class. For property {@code foo}, this will be {@code foo} or {@code\n     * getFoo} or {@code isFoo}. For AutoBuilder, the getter in question is the one that will be\n     * called on the built type to derive the value of the property, in the copy constructor.\n     */\n    public String getGetter() {\n      return getter;\n    }\n\n    boolean hasDefault() {\n      return hasDefault;\n    }\n  }\n\n  /** A {@link Property} that corresponds to an abstract getter method in the source. */\n  public static class GetterProperty extends Property {\n    private final ExecutableElement method;\n    private final ImmutableList<String> fieldAnnotations;\n    private final ImmutableList<String> methodAnnotations;\n\n    GetterProperty(\n        String name,\n        String identifier,\n        ExecutableElement method,\n        AnnotatedTypeMirror annotatedType,\n        String typeString,\n        ImmutableList<String> fieldAnnotations,\n        ImmutableList<String> methodAnnotations,\n        Optional<String> nullableAnnotation,\n        Nullables nullables) {\n      super(\n          name,\n          identifier,\n          typeString,\n          annotatedType,\n          nullableAnnotation,\n          nullables,\n          method.getSimpleName().toString(),\n          Optional.empty(),\n          /* hasDefault= */ false);\n      this.method = method;\n      this.fieldAnnotations = fieldAnnotations;\n      this.methodAnnotations = methodAnnotations;\n    }\n\n    /**\n     * Returns the annotations (in string form) that should be applied to the property's field\n     * declaration.\n     */\n    public List<String> getFieldAnnotations() {\n      return fieldAnnotations;\n    }\n\n    /**\n     * Returns the annotations (in string form) that should be applied to the property's method\n     * implementation.\n     */\n    public List<String> getMethodAnnotations() {\n      return methodAnnotations;\n    }\n\n    public String getAccess() {\n      return SimpleMethod.access(method);\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n      return obj instanceof GetterProperty && ((GetterProperty) obj).method.equals(method);\n    }\n\n    @Override\n    public int hashCode() {\n      return method.hashCode();\n    }\n  }\n\n  void addDeferredType(TypeElement type, String missingType) {\n    // We save the name of the type containing the problem, rather than its TypeElement, because it\n    // is not guaranteed that it will be represented by the same TypeElement on the next round. We\n    // save the name of the missing type for better diagnostics. (It may be empty.)\n    deferredTypeNames.put(type.getQualifiedName().toString(), missingType);\n  }\n\n  @Override\n  public final boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n    if (annotationType == null) {\n      // This should not happen. If the annotation type is not found, how did the processor get\n      // triggered?\n      processingEnv\n          .getMessager()\n          .printMessage(\n              Diagnostic.Kind.ERROR,\n              \"Did not process @\"\n                  + annotationClassName\n                  + \" because the annotation class was not found\");\n      return false;\n    }\n    ImmutableMap<TypeElement, String> deferredTypes =\n        deferredTypeNames.entrySet().stream()\n            .collect(\n                toImmutableMap(\n                    entry -> elementUtils().getTypeElement(entry.getKey()), Map.Entry::getValue));\n    if (roundEnv.processingOver()) {\n      // This means that the previous round didn't generate any new sources, so we can't have found\n      // any new instances of @AutoValue; and we can't have any new types that are the reason a type\n      // was in deferredTypes.\n      deferredTypes.forEach(\n          (type, missing) -> {\n            String including = missing.isEmpty() ? \"\" : (\"including \" + missing);\n            errorReporter.reportError(\n                type,\n                \"[%sUndefined] Did not generate @%s class for %s because it references\"\n                    + \" undefined types %s\",\n                simpleAnnotationName,\n                simpleAnnotationName,\n                type.getQualifiedName(),\n                including);\n          });\n      return false;\n    }\n    Collection<? extends Element> annotatedElements =\n        roundEnv.getElementsAnnotatedWith(annotationType);\n    List<TypeElement> types =\n        new ImmutableList.Builder<TypeElement>()\n            .addAll(deferredTypes.keySet())\n            .addAll(ElementFilter.typesIn(annotatedElements))\n            .build();\n    deferredTypeNames.clear();\n    for (TypeElement type : types) {\n      try {\n        validateType(type);\n        processType(type);\n      } catch (AbortProcessingException e) {\n        // We abandoned this type; continue with the next.\n      } catch (MissingTypeException e) {\n        // We abandoned this type, but only because we needed another type that it references and\n        // that other type was missing. It is possible that the missing type will be generated by\n        // further annotation processing, so we will try again on the next round (perhaps failing\n        // again and adding it back to the list).\n        addDeferredType(type, e.getMessage());\n      } catch (RuntimeException e) {\n        String trace = Throwables.getStackTraceAsString(e);\n        errorReporter.reportError(\n            type,\n            \"[%sException] @%s processor threw an exception: %s\",\n            simpleAnnotationName,\n            simpleAnnotationName,\n            trace);\n        throw e;\n      }\n    }\n    return false; // never claim annotation, because who knows what other processors want?\n  }\n\n  /**\n   * Validations common to all the subclasses. An {@code @AutoFoo} type must be a class, or possibly\n   * an interface for {@code @AutoBuilder}. If it is a class then it must have a non-private no-arg\n   * constructor. And, since we'll be generating a subclass, it can't be final.\n   */\n  private void validateType(TypeElement type) {\n    ElementKind kind = type.getKind();\n    boolean kindOk =\n        kind.equals(ElementKind.CLASS)\n            || (appliesToInterfaces && kind.equals(ElementKind.INTERFACE));\n    if (!kindOk) {\n      String appliesTo = appliesToInterfaces ? \"classes and interfaces\" : \"classes\";\n      errorReporter.abortWithError(\n          type,\n          \"[%sWrongType] @%s only applies to %s\",\n          simpleAnnotationName,\n          simpleAnnotationName,\n          appliesTo);\n    }\n    checkModifiersIfNested(type);\n    if (!hasVisibleNoArgConstructor(type)) {\n      errorReporter.reportError(\n          type,\n          \"[%sConstructor] @%s class must have a non-private no-arg constructor\",\n          simpleAnnotationName,\n          simpleAnnotationName);\n    }\n    if (type.getModifiers().contains(Modifier.FINAL)) {\n      errorReporter.abortWithError(\n          type,\n          \"[%sFinal] @%s class must not be final\",\n          simpleAnnotationName,\n          simpleAnnotationName);\n    }\n  }\n\n  /**\n   * Analyzes a single {@code @AutoValue} (etc) class, and outputs the corresponding implementation\n   * class or classes.\n   *\n   * @param type the class with the {@code @AutoValue} or {@code @AutoOneOf} annotation.\n   */\n  abstract void processType(TypeElement type);\n\n  /**\n   * Returns the appropriate {@code @Nullable} annotation to put on the implementation of the given\n   * property method, and indicates whether the property is in fact nullable. The annotation in\n   * question is on the method, not its return type. If instead the return type is\n   * {@code @Nullable}, this method returns {@code Optional.of(\"\")}, to indicate that the property\n   * is nullable but the <i>method</i> isn't. The {@code @Nullable} annotation will instead appear\n   * when the return type of the method is spelled out in the implementation.\n   */\n  abstract Optional<String> nullableAnnotationForMethod(ExecutableElement propertyMethod);\n\n  /**\n   * Returns the ordered set of {@link Property} definitions for the given {@code @AutoValue} or\n   * {@code AutoOneOf} type.\n   *\n   * @param annotatedPropertyMethods a map from property methods to the method annotations that\n   *     should go on the implementation of those methods. These annotations are method annotations\n   *     specifically. Type annotations do not appear because they are considered part of the return\n   *     type and will appear when that is spelled out. Annotations that are excluded by {@code\n   *     AutoValue.CopyAnnotations} also do not appear here.\n   */\n  final ImmutableSet<Property> propertySet(\n      ImmutableMap<ExecutableElement, AnnotatedTypeMirror> propertyMethodsAndTypes,\n      ImmutableListMultimap<ExecutableElement, AnnotationMirror> annotatedPropertyFields,\n      ImmutableListMultimap<ExecutableElement, AnnotationMirror> annotatedPropertyMethods,\n      Nullables nullables) {\n    ImmutableBiMap<ExecutableElement, String> methodToPropertyName =\n        propertyNameToMethodMap(propertyMethodsAndTypes.keySet()).inverse();\n    Map<ExecutableElement, String> methodToIdentifier = new LinkedHashMap<>(methodToPropertyName);\n    fixReservedIdentifiers(methodToIdentifier);\n\n    ImmutableSet.Builder<Property> props = ImmutableSet.builder();\n    propertyMethodsAndTypes.forEach(\n        (propertyMethod, returnType) -> {\n          String propertyTypeString =\n              TypeEncoder.encodeWithAnnotations(\n                  returnType, ImmutableList.of(), getExcludedAnnotationTypes(propertyMethod));\n          String propertyName = methodToPropertyName.get(propertyMethod);\n          String identifier = methodToIdentifier.get(propertyMethod);\n          ImmutableList<String> fieldAnnotations =\n              annotationStrings(annotatedPropertyFields.get(propertyMethod));\n          ImmutableList<AnnotationMirror> methodAnnotationMirrors =\n              annotatedPropertyMethods.get(propertyMethod);\n          ImmutableList<String> methodAnnotations = annotationStrings(methodAnnotationMirrors);\n          Optional<String> nullableAnnotation = nullableAnnotationForMethod(propertyMethod);\n          Property p =\n              new GetterProperty(\n                  propertyName,\n                  identifier,\n                  propertyMethod,\n                  returnType,\n                  propertyTypeString,\n                  fieldAnnotations,\n                  methodAnnotations,\n                  nullableAnnotation,\n                  nullables);\n          props.add(p);\n          if (p.isNullable() && returnType.getKind().isPrimitive()) {\n            errorReporter()\n                .reportError(\n                    propertyMethod,\n                    \"[%sNullPrimitive] Primitive types cannot be @Nullable\",\n                    simpleAnnotationName);\n          }\n        });\n    return props.build();\n  }\n\n  /** Defines the template variables that are shared by AutoValue, AutoOneOf, and AutoBuilder. */\n  final void defineSharedVarsForType(\n      TypeElement type,\n      ImmutableSet<ExecutableElement> methods,\n      Nullables nullables,\n      AutoValueishTemplateVars vars) {\n    vars.pkg = TypeSimplifier.packageNameOf(type);\n    vars.origClass = TypeSimplifier.classNameOf(type);\n    vars.simpleClassName = TypeSimplifier.simpleNameOf(vars.origClass);\n    vars.generated =\n        generatedAnnotation(elementUtils(), processingEnv.getSourceVersion())\n            .map(annotation -> TypeEncoder.encode(annotation.asType()))\n            .orElse(\"\");\n    vars.formalTypes = TypeEncoder.typeParametersString(type.getTypeParameters());\n    vars.actualTypes = TypeSimplifier.actualTypeParametersString(type);\n    vars.wildcardTypes = wildcardTypeParametersString(type);\n    vars.annotations = copiedClassAnnotations(type);\n    Map<ObjectMethod, ExecutableElement> methodsToGenerate =\n        determineObjectMethodsToGenerate(methods);\n    vars.toString = methodsToGenerate.containsKey(ObjectMethod.TO_STRING);\n    vars.equals = methodsToGenerate.containsKey(ObjectMethod.EQUALS);\n    vars.hashCode = methodsToGenerate.containsKey(ObjectMethod.HASH_CODE);\n    vars.equalsParameterType = equalsParameterType(methodsToGenerate, nullables);\n    vars.serialVersionUID = getSerialVersionUID(type);\n  }\n\n  /** Returns the spelling to be used in the generated code for the given list of annotations. */\n  static ImmutableList<String> annotationStrings(List<? extends AnnotationMirror> annotations) {\n    return annotations.stream()\n        .map(AnnotationOutput::sourceFormForAnnotation)\n        .sorted() // ensures deterministic order\n        .collect(toImmutableList());\n  }\n\n  /**\n   * Returns the name of the generated {@code @AutoValue} (etc) class, for example {@code\n   * AutoOneOf_TaskResult} or {@code $$AutoValue_SimpleMethod}.\n   *\n   * @param type the name of the type bearing the {@code @AutoValue} (etc) annotation.\n   * @param prefix the prefix to use in the generated class. This may start with one or more dollar\n   *     signs, for an {@code @AutoValue} implementation where there are AutoValue extensions.\n   */\n  static String generatedClassName(TypeElement type, String prefix) {\n    String name = type.getSimpleName().toString();\n    while (MoreElements.isType(type.getEnclosingElement())) {\n      type = MoreElements.asType(type.getEnclosingElement());\n      name = type.getSimpleName() + \"_\" + name;\n    }\n    String pkg = TypeSimplifier.packageNameOf(type);\n    String dot = pkg.isEmpty() ? \"\" : \".\";\n    return pkg + dot + prefix + name;\n  }\n\n  private static boolean isJavaLangObject(TypeElement type) {\n    return type.getSuperclass().getKind() == TypeKind.NONE && type.getKind() == ElementKind.CLASS;\n  }\n\n  enum ObjectMethod {\n    NONE,\n    TO_STRING,\n    EQUALS,\n    HASH_CODE\n  }\n\n  /**\n   * Determines which of the three public non-final methods from {@code java.lang.Object}, if any,\n   * is overridden by the given method.\n   */\n  static ObjectMethod objectMethodToOverride(ExecutableElement method) {\n    String name = method.getSimpleName().toString();\n    switch (method.getParameters().size()) {\n      case 0:\n        if (name.equals(\"toString\")) {\n          return ObjectMethod.TO_STRING;\n        } else if (name.equals(\"hashCode\")) {\n          return ObjectMethod.HASH_CODE;\n        }\n        break;\n      case 1:\n        if (name.equals(\"equals\")) {\n          TypeMirror param = getOnlyElement(method.getParameters()).asType();\n          if (param.getKind().equals(TypeKind.DECLARED)) {\n            TypeElement paramType = MoreTypes.asTypeElement(param);\n            if (paramType.getQualifiedName().contentEquals(\"java.lang.Object\")) {\n              return ObjectMethod.EQUALS;\n            }\n          }\n        }\n        break;\n      default:\n        // No relevant Object methods have more than one parameter.\n    }\n    return ObjectMethod.NONE;\n  }\n\n  /** Returns a bi-map between property names and the corresponding abstract property methods. */\n  final ImmutableBiMap<String, ExecutableElement> propertyNameToMethodMap(\n      Set<ExecutableElement> propertyMethods) {\n    Map<String, ExecutableElement> map = new LinkedHashMap<>();\n    Set<String> reportedDups = new HashSet<>();\n    boolean allPrefixed = gettersAllPrefixed(propertyMethods);\n    for (ExecutableElement method : propertyMethods) {\n      String methodName = method.getSimpleName().toString();\n      String name = allPrefixed ? nameWithoutPrefix(methodName) : methodName;\n      ExecutableElement old = map.put(name, method);\n      if (old != null) {\n        List<ExecutableElement> contexts = new ArrayList<>(Arrays.asList(method));\n        if (reportedDups.add(name)) {\n          contexts.add(old);\n        }\n        // Report the error for both of the methods. If this is a third or further occurrence,\n        // reportedDups prevents us from reporting more than one error for the same method.\n        for (ExecutableElement context : contexts) {\n          errorReporter.reportError(\n              context,\n              \"[%sDupProperty] More than one @%s property called %s\",\n              simpleAnnotationName,\n              simpleAnnotationName,\n              name);\n        }\n      }\n    }\n    return ImmutableBiMap.copyOf(map);\n  }\n\n  private static boolean gettersAllPrefixed(Set<ExecutableElement> methods) {\n    return prefixedGettersIn(methods).size() == methods.size();\n  }\n\n  /**\n   * Returns an appropriate annotation spelling to indicate the nullability of an element. If the\n   * return value is a non-empty Optional, that indicates that the element is nullable, and the\n   * string should be used to annotate it. If the return value is an empty Optional, the element is\n   * not nullable. The return value can be {@code Optional.of(\"\")}, which indicates that the element\n   * is nullable but that the nullability comes from a type annotation. In this case, the annotation\n   * will appear when the type is written, and must not be specified again. If the Optional contains\n   * a present non-empty string then that string will end with a space.\n   *\n   * @param element the element that might be {@code @Nullable}, either a method or a parameter.\n   * @param elementType the relevant type of the element: the return type for a method, or the\n   *     parameter type for a parameter.\n   */\n  static Optional<String> nullableAnnotationFor(Element element, TypeMirror elementType) {\n    if (isNullable(elementType)) {\n      return Optional.of(\"\");\n    }\n    List<? extends AnnotationMirror> elementAnnotations = element.getAnnotationMirrors();\n    OptionalInt nullableAnnotationIndex = nullableAnnotationIndex(elementAnnotations);\n    if (nullableAnnotationIndex.isPresent()) {\n      AnnotationMirror annotation = elementAnnotations.get(nullableAnnotationIndex.getAsInt());\n      String annotationString = AnnotationOutput.sourceFormForAnnotation(annotation);\n      return Optional.of(annotationString + \" \");\n    } else {\n      return Optional.empty();\n    }\n  }\n\n  private static OptionalInt nullableAnnotationIndex(List<? extends AnnotationMirror> annotations) {\n    return IntStream.range(0, annotations.size())\n        .filter(i -> isNullable(annotations.get(i)))\n        .findFirst();\n  }\n\n  private static boolean isNullable(TypeMirror type) {\n    return isNullable(type, 0);\n  }\n\n  private static boolean isNullable(TypeMirror type, int depth) {\n    // Some versions of the Eclipse compiler can report that the upper bound of a type variable T\n    // is another T, and if you ask for the upper bound of that other T you'll get a third T, and so\n    // ad infinitum. To avoid StackOverflowError, we bottom out after 10 iterations.\n    if (depth > 10) {\n      return false;\n    }\n    List<? extends AnnotationMirror> typeAnnotations = type.getAnnotationMirrors();\n    // TODO(emcmanus): also check if there is a @NonNull bound and return false if so.\n    if (nullableAnnotationIndex(typeAnnotations).isPresent()) {\n      return true;\n    }\n    if (type.getKind().equals(TypeKind.TYPEVAR)) {\n      TypeVariable typeVariable = MoreTypes.asTypeVariable(type);\n      TypeMirror bound = typeVariable.getUpperBound();\n      if (bound.getKind().equals(TypeKind.INTERSECTION)) {\n        return MoreTypes.asIntersection(bound).getBounds().stream()\n            .allMatch(t -> isNullable(t, depth + 1));\n      }\n      return isNullable(bound, depth + 1);\n    }\n    return false;\n  }\n\n  private static boolean isNullable(AnnotationMirror annotation) {\n    return annotation.getAnnotationType().asElement().getSimpleName().contentEquals(\"Nullable\");\n  }\n\n  /**\n   * Returns the subset of the given zero-arg methods whose names begin with {@code get}. Also\n   * includes {@code isFoo} methods if they return {@code boolean}. This corresponds to JavaBeans\n   * conventions.\n   */\n  static ImmutableSet<ExecutableElement> prefixedGettersIn(Collection<ExecutableElement> methods) {\n    return methods.stream()\n        .filter(AutoValueishProcessor::isPrefixedGetter)\n        .collect(toImmutableSet());\n  }\n\n  static boolean isPrefixedGetter(ExecutableElement method) {\n    String name = method.getSimpleName().toString();\n    // Note that getfoo() (without a capital) is still a getter.\n    return (name.startsWith(\"get\") && !name.equals(\"get\"))\n        || (name.startsWith(\"is\")\n            && !name.equals(\"is\")\n            && method.getReturnType().getKind() == TypeKind.BOOLEAN);\n  }\n\n  /**\n   * Returns the name of the property defined by the given getter. A getter called {@code getFoo()}\n   * or {@code isFoo()} defines a property called {@code foo}. For consistency with JavaBeans, a\n   * getter called {@code getHTMLPage()} defines a property called {@code HTMLPage}. The <a\n   * href=\"https://docs.oracle.com/javase/8/docs/api/java/beans/Introspector.html#decapitalize-java.lang.String-\">\n   * rule</a> is: the name of the property is the part after {@code get} or {@code is}, with the\n   * first letter lowercased <i>unless</i> the first two letters are uppercase. This works well for\n   * the {@code HTMLPage} example, but in these more enlightened times we use {@code HtmlPage}\n   * anyway, so the special behaviour is not useful, and of course it behaves poorly with examples\n   * like {@code OAuth}.\n   */\n  static String nameWithoutPrefix(String name) {\n    if (name.startsWith(\"get\")) {\n      name = name.substring(3);\n    } else {\n      assert name.startsWith(\"is\");\n      name = name.substring(2);\n    }\n    return PropertyNames.decapitalizeLikeJavaBeans(name);\n  }\n\n  /**\n   * Checks that, if the given {@code @AutoValue}, {@code @AutoOneOf}, or {@code @AutoBuilder} class\n   * is nested, it is static and not private. This check is not necessary for correctness, since the\n   * generated code would not compile if the check fails, but it produces better error messages for\n   * the user.\n   */\n  final void checkModifiersIfNested(TypeElement type) {\n    checkModifiersIfNested(type, type, simpleAnnotationName);\n  }\n\n  final void checkModifiersIfNested(TypeElement type, TypeElement reportedType, String what) {\n    ElementKind enclosingKind = type.getEnclosingElement().getKind();\n    if (enclosingKind.isClass() || enclosingKind.isInterface()) {\n      if (type.getModifiers().contains(Modifier.PRIVATE)) {\n        errorReporter.abortWithError(\n            reportedType, \"[%sPrivate] @%s class must not be private\", simpleAnnotationName, what);\n      } else if (Visibility.effectiveVisibilityOfElement(type).equals(Visibility.PRIVATE)) {\n        // The previous case, where the class itself is private, is much commoner so it deserves\n        // its own error message, even though it would be caught by the test here too.\n        errorReporter.abortWithError(\n            reportedType,\n            \"[%sInPrivate] @%s class must not be nested in a private class\",\n            simpleAnnotationName,\n            what);\n      }\n      if (!type.getModifiers().contains(Modifier.STATIC)) {\n        errorReporter.abortWithError(\n            reportedType, \"[%sInner] Nested @%s class must be static\", simpleAnnotationName, what);\n      }\n    }\n    // In principle type.getEnclosingElement() could be an ExecutableElement (for a class\n    // declared inside a method), but since RoundEnvironment.getElementsAnnotatedWith doesn't\n    // return such classes we won't see them here.\n  }\n\n  /**\n   * Modifies the values of the given map to avoid reserved words. If we have a getter called {@code\n   * getPackage()} then we can't use the identifier {@code package} to represent its value since\n   * that's a reserved word.\n   */\n  static void fixReservedIdentifiers(Map<?, String> methodToIdentifier) {\n    for (Map.Entry<?, String> entry : methodToIdentifier.entrySet()) {\n      String name = entry.getValue();\n      if (SourceVersion.isKeyword(name) || !Character.isJavaIdentifierStart(name.codePointAt(0))) {\n        entry.setValue(disambiguate(name, methodToIdentifier.values()));\n      }\n    }\n  }\n\n  private static String disambiguate(String name, Collection<String> existingNames) {\n    if (!Character.isJavaIdentifierStart(name.codePointAt(0))) {\n      // You've defined a getter called get1st(). What were you thinking?\n      name = \"_\" + name;\n      if (!existingNames.contains(name)) {\n        return name;\n      }\n    }\n    for (int i = 0; ; i++) {\n      String candidate = name + i;\n      if (!existingNames.contains(candidate)) {\n        return candidate;\n      }\n    }\n  }\n\n  /**\n   * Given a list of all methods defined in or inherited by a class, returns a map indicating which\n   * of equals, hashCode, and toString should be generated. Each value in the map is the method that\n   * will be overridden by the generated method, which might be a method in {@code Object} or an\n   * abstract method in the {@code @AutoValue} class or an ancestor.\n   */\n  private static Map<ObjectMethod, ExecutableElement> determineObjectMethodsToGenerate(\n      Set<ExecutableElement> methods) {\n    Map<ObjectMethod, ExecutableElement> methodsToGenerate = new EnumMap<>(ObjectMethod.class);\n    for (ExecutableElement method : methods) {\n      ObjectMethod override = objectMethodToOverride(method);\n      boolean canGenerate =\n          method.getModifiers().contains(Modifier.ABSTRACT)\n              || isJavaLangObject(MoreElements.asType(method.getEnclosingElement()));\n      if (!override.equals(ObjectMethod.NONE) && canGenerate) {\n        methodsToGenerate.put(override, method);\n      }\n    }\n    return methodsToGenerate;\n  }\n\n  /**\n   * Returns the encoded parameter type of the {@code equals(Object)} method that is to be\n   * generated, or an empty string if the method is not being generated. The parameter type includes\n   * any type annotations, for example {@code @Nullable}.\n   *\n   * @param methodsToGenerate the Object methods that are being generated\n   * @param nullable the type of a {@code @Nullable} type annotation that we have found, if any\n   */\n  static String equalsParameterType(\n      Map<ObjectMethod, ExecutableElement> methodsToGenerate, Nullables nullables) {\n    ExecutableElement equals = methodsToGenerate.get(ObjectMethod.EQUALS);\n    if (equals == null) {\n      return \"\"; // this will not be referenced because no equals method will be generated\n    }\n    TypeMirror parameterType = equals.getParameters().get(0).asType();\n    // Add @Nullable if we know one and the parameter doesn't already have one.\n    // The @Nullable we add will be a type annotation, but if the parameter already has @Nullable\n    // then that might be a type annotation or an annotation on the parameter.\n    ImmutableList<AnnotationMirror> extraAnnotations =\n        nullableAnnotationFor(equals, parameterType).isPresent()\n            ? ImmutableList.of()\n            : nullables.nullableTypeAnnotations();\n    return TypeEncoder.encodeWithAnnotations(parameterType, extraAnnotations);\n  }\n\n  /**\n   * Returns the subset of all abstract methods in the given set of methods. A given method\n   * signature is only mentioned once, even if it is inherited on more than one path. If any of the\n   * abstract methods has a return type or parameter type that is not currently defined then this\n   * method will throw an exception that will cause us to defer processing of the current class\n   * until a later annotation-processing round.\n   */\n  static ImmutableSet<ExecutableElement> abstractMethodsIn(Iterable<ExecutableElement> methods) {\n    Set<Name> noArgMethods = new HashSet<>();\n    ImmutableSet.Builder<ExecutableElement> abstracts = ImmutableSet.builder();\n    for (ExecutableElement method : methods) {\n      if (method.getModifiers().contains(Modifier.ABSTRACT)) {\n        MissingTypes.deferIfMissingTypesIn(method);\n        boolean hasArgs = !method.getParameters().isEmpty();\n        if (hasArgs || noArgMethods.add(method.getSimpleName())) {\n          // If an abstract method with the same signature is inherited on more than one path,\n          // we only add it once. At the moment we only do this check for no-arg methods. All\n          // methods that AutoValue will implement are either no-arg methods or equals(Object).\n          // The former is covered by this check and the latter will lead to vars.equals being\n          // set to true, regardless of how many times it appears. So the only case that is\n          // covered imperfectly here is that of a method that is inherited on more than one path\n          // and that will be consumed by an extension. We could check parameters as well, but that\n          // can be a bit tricky if any of the parameters are generic.\n          abstracts.add(method);\n        }\n      }\n    }\n    return abstracts.build();\n  }\n\n  /**\n   * Returns the subset of property methods in the given set of abstract methods, with their actual\n   * return types. A property method has no arguments, is not void, and is not {@code hashCode()} or\n   * {@code toString()}.\n   */\n  ImmutableMap<ExecutableElement, AnnotatedTypeMirror> propertyMethodsIn(\n      Set<ExecutableElement> abstractMethods, TypeElement autoValueOrOneOfType) {\n    return abstractMethods.stream()\n        .filter(\n            method ->\n                method.getParameters().isEmpty()\n                    && (method.getReturnType().getKind() != TypeKind.VOID || propertiesCanBeVoid())\n                    && objectMethodToOverride(method) == ObjectMethod.NONE)\n        .collect(\n            toImmutableMap(\n                method -> method,\n                method ->\n                    MethodSignature.asMemberOf(typeUtils(), autoValueOrOneOfType, method)\n                        .returnType()));\n  }\n\n  /** True if void properties are allowed. */\n  boolean propertiesCanBeVoid() {\n    return false;\n  }\n\n  /**\n   * Checks that the return type of the given property method is allowed. Currently, this means that\n   * it cannot be an array, unless it is a primitive array.\n   */\n  final void checkReturnType(TypeElement autoValueClass, ExecutableElement getter) {\n    TypeMirror type = getter.getReturnType();\n    if (type.getKind() == TypeKind.ARRAY) {\n      TypeMirror componentType = MoreTypes.asArray(type).getComponentType();\n      if (componentType.getKind().isPrimitive()) {\n        warnAboutPrimitiveArrays(autoValueClass, getter);\n      } else {\n        errorReporter.reportError(\n            getter,\n            \"[AutoValueArray] An @%s class cannot define an array-valued property unless it is a\"\n                + \" primitive array\",\n            simpleAnnotationName);\n      }\n    }\n  }\n\n  private void warnAboutPrimitiveArrays(TypeElement autoValueClass, ExecutableElement getter) {\n    boolean suppressed = false;\n    Optional<AnnotationMirror> maybeAnnotation =\n        getAnnotationMirror(getter, \"java.lang.SuppressWarnings\");\n    if (maybeAnnotation.isPresent()) {\n      AnnotationValue listValue = getAnnotationValue(maybeAnnotation.get(), \"value\");\n      suppressed = listValue.accept(new ContainsMutableVisitor(), null);\n    }\n    if (!suppressed) {\n      // If the primitive-array property method is defined directly inside the @AutoValue class,\n      // then our error message should point directly to it. But if it is inherited, we don't\n      // want to try to make the error message point to the inherited definition, since that would\n      // be confusing (there is nothing wrong with the definition itself), and won't work if the\n      // inherited class is not being recompiled. Instead, in this case we point to the @AutoValue\n      // class itself, and we include extra text in the error message that shows the full name of\n      // the inherited method.\n      boolean sameClass = getter.getEnclosingElement().equals(autoValueClass);\n      Element element = sameClass ? getter : autoValueClass;\n      String context = sameClass ? \"\" : (\" Method: \" + getter.getEnclosingElement() + \".\" + getter);\n      errorReporter.reportWarning(\n          element,\n          \"[AutoValueMutable] An @%s property that is a primitive array returns the original\"\n              + \" array, which can therefore be modified by the caller. If this is OK, you can\"\n              + \" suppress this warning with @SuppressWarnings(\\\"mutable\\\"). Otherwise, you should\"\n              + \" replace the property with an immutable type, perhaps a simple wrapper around the\"\n              + \" original array.%s\",\n          simpleAnnotationName,\n          context);\n    }\n  }\n\n  // Detects whether the visited AnnotationValue is an array that contains the string \"mutable\".\n  // The simpler approach using Element.getAnnotation(SuppressWarnings.class) doesn't work if\n  // the annotation has an undefined reference, like @SuppressWarnings(UNDEFINED).\n  // TODO(emcmanus): replace with a method from auto-common when that is available.\n  private static class ContainsMutableVisitor extends SimpleAnnotationValueVisitor8<Boolean, Void> {\n    @Override\n    public Boolean visitArray(List<? extends AnnotationValue> list, Void p) {\n      return list.stream().map(AnnotationValue::getValue).anyMatch(\"mutable\"::equals);\n    }\n  }\n\n  /**\n   * Returns a string like {@code \"private static final long serialVersionUID = 1234L\"} if {@code\n   * type instanceof Serializable} and defines {@code serialVersionUID = 1234L}; otherwise {@code\n   * \"\"}.\n   */\n  final String getSerialVersionUID(TypeElement type) {\n    TypeMirror serializable = elementUtils().getTypeElement(Serializable.class.getName()).asType();\n    if (typeUtils().isAssignable(type.asType(), serializable)) {\n      List<VariableElement> fields = ElementFilter.fieldsIn(type.getEnclosedElements());\n      for (VariableElement field : fields) {\n        if (field.getSimpleName().contentEquals(\"serialVersionUID\")) {\n          Object value = field.getConstantValue();\n          if (field.getModifiers().containsAll(Arrays.asList(Modifier.STATIC, Modifier.FINAL))\n              && field.asType().getKind() == TypeKind.LONG\n              && value != null) {\n            return \"private static final long serialVersionUID = \" + value + \"L;\";\n          } else {\n            errorReporter.reportError(\n                field, \"serialVersionUID must be a static final long compile-time constant\");\n            break;\n          }\n        }\n      }\n    }\n    return \"\";\n  }\n\n  /** Implements the semantics of {@code AutoValue.CopyAnnotations}; see its javadoc. */\n  ImmutableList<AnnotationMirror> annotationsToCopy(\n      Element autoValueType, Element typeOrMethod, Set<String> excludedAnnotations) {\n    ImmutableList.Builder<AnnotationMirror> result = ImmutableList.builder();\n    for (AnnotationMirror annotation : typeOrMethod.getAnnotationMirrors()) {\n      String annotationFqName = getAnnotationFqName(annotation);\n      // To be included, the annotation should not be in com.google.auto.value,\n      // and it should not be in the excludedAnnotations set.\n      if (!isInAutoValuePackage(annotationFqName)\n          && !excludedAnnotations.contains(annotationFqName)\n          && annotationVisibleFrom(annotation, autoValueType)) {\n        result.add(annotation);\n      }\n    }\n\n    return result.build();\n  }\n\n  /**\n   * True if the given class name is in the com.google.auto.value package or a subpackage. False if\n   * the class name contains {@code Test}, since many AutoValue tests under com.google.auto.value\n   * define their own annotations.\n   */\n  private static boolean isInAutoValuePackage(String className) {\n    return className.startsWith(AUTO_VALUE_PACKAGE_NAME) && !className.contains(\"Test\");\n  }\n\n  ImmutableList<String> copiedClassAnnotations(TypeElement type) {\n    // Only copy annotations from a class if it has @AutoValue.CopyAnnotations.\n    if (hasAnnotationMirror(type, COPY_ANNOTATIONS_NAME)) {\n      Set<String> excludedAnnotations =\n          ImmutableSet.<String>builder()\n              .addAll(getExcludedAnnotationClassNames(type))\n              .addAll(getAnnotationsMarkedWithInherited(type))\n              //\n              // Kotlin classes have an intrinsic @Metadata annotation generated\n              // onto them by kotlinc. This annotation is specific to the annotated\n              // class and should not be implicitly copied. Doing so can mislead\n              // static analysis or metaprogramming tooling that reads the data\n              // contained in these annotations.\n              //\n              // It may be surprising to see AutoValue classes written in Kotlin\n              // when they could be written as Kotlin data classes, but this can\n              // come up in cases where consumers rely on AutoValue features or\n              // extensions that are not available in data classes.\n              //\n              // See: https://github.com/google/auto/issues/1087\n              //\n              .add(ClassNames.KOTLIN_METADATA_NAME)\n              .build();\n\n      return copyAnnotations(type, type, excludedAnnotations);\n    } else {\n      return ImmutableList.of();\n    }\n  }\n\n  /** Implements the semantics of {@code AutoValue.CopyAnnotations}; see its javadoc. */\n  ImmutableList<String> copyAnnotations(\n      Element autoValueType, Element typeOrMethod, Set<String> excludedAnnotations) {\n    ImmutableList<AnnotationMirror> annotationsToCopy =\n        annotationsToCopy(autoValueType, typeOrMethod, excludedAnnotations);\n    return annotationStrings(annotationsToCopy);\n  }\n\n  /**\n   * Returns the contents of the {@code AutoValue.CopyAnnotations.exclude} element, as a set of\n   * {@code TypeMirror} where each type is an annotation type.\n   */\n  private static Set<TypeMirror> getExcludedAnnotationTypes(Element element) {\n    Optional<AnnotationMirror> maybeAnnotation =\n        getAnnotationMirror(element, COPY_ANNOTATIONS_NAME);\n    if (!maybeAnnotation.isPresent()) {\n      return ImmutableSet.of();\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    List<AnnotationValue> excludedClasses =\n        (List<AnnotationValue>) getAnnotationValue(maybeAnnotation.get(), \"exclude\").getValue();\n    // It turns out that if you write `@AutoValue.CopyAnnotations(exclude = {Missing.class})`, where\n    // `Missing` is a class that does not exist, then javac will represent it as a String in the\n    // AnnotationValue, rather than an ErrorType as you might expect. So we filter out anything that\n    // is not a DeclaredType. (ErrorType *is* a DeclaredType.) Presumably you'll get a compilation\n    // error because of the missing class. If another compiler uses ErrorType instead of String,\n    // then we'll just add that ErrorType to the returned TypeMirrorSet here, where it will\n    // presumably be ignored, or perhaps match the ErrorType for `@Missing` somewhere else in the\n    // code.\n    // This is a pretty obscure case so our main concern here is to avoid a ClassCastException.\n    return excludedClasses.stream()\n        .map(AnnotationValue::getValue)\n        .filter(DeclaredType.class::isInstance)\n        .map(DeclaredType.class::cast)\n        .collect(toCollection(TypeMirrorSet::new));\n  }\n\n  /**\n   * Returns the contents of the {@code AutoValue.CopyAnnotations.exclude} element, as a set of\n   * strings that are fully-qualified class names.\n   */\n  static Set<String> getExcludedAnnotationClassNames(Element element) {\n    return getExcludedAnnotationTypes(element).stream()\n        .map(MoreTypes::asTypeElement)\n        .map(typeElement -> typeElement.getQualifiedName().toString())\n        .collect(toSet());\n  }\n\n  static Set<String> getAnnotationsMarkedWithInherited(Element element) {\n    return element.getAnnotationMirrors().stream()\n        .filter(a -> isAnnotationPresent(a.getAnnotationType().asElement(), Inherited.class))\n        .map(a -> getAnnotationFqName(a))\n        .collect(toSet());\n  }\n\n  /**\n   * Returns the fully-qualified name of an annotation-mirror, e.g.\n   * \"com.google.auto.value.AutoValue\".\n   */\n  private static String getAnnotationFqName(AnnotationMirror annotation) {\n    return ((QualifiedNameable) annotation.getAnnotationType().asElement())\n        .getQualifiedName()\n        .toString();\n  }\n\n  ImmutableListMultimap<ExecutableElement, AnnotationMirror> propertyMethodAnnotationMap(\n      TypeElement type, ImmutableSet<ExecutableElement> propertyMethods) {\n    ImmutableListMultimap.Builder<ExecutableElement, AnnotationMirror> builder =\n        ImmutableListMultimap.builder();\n    for (ExecutableElement propertyMethod : propertyMethods) {\n      builder.putAll(propertyMethod, propertyMethodAnnotations(type, propertyMethod));\n    }\n    return builder.build();\n  }\n\n  ImmutableList<AnnotationMirror> propertyMethodAnnotations(\n      TypeElement type, ExecutableElement method) {\n    ImmutableSet<String> excludedAnnotations =\n        ImmutableSet.<String>builder()\n            .addAll(getExcludedAnnotationClassNames(method))\n            .add(Override.class.getCanonicalName())\n            .build();\n\n    // We need to exclude type annotations from the ones being output on the method, since\n    // they will be output as part of the method's return type.\n    Set<String> returnTypeAnnotations = getReturnTypeAnnotations(method, a -> true);\n    Set<String> excluded = union(excludedAnnotations, returnTypeAnnotations);\n    return annotationsToCopy(type, method, excluded);\n  }\n\n  final ImmutableListMultimap<ExecutableElement, AnnotationMirror> propertyFieldAnnotationMap(\n      TypeElement type, ImmutableSet<ExecutableElement> propertyMethods) {\n    ImmutableListMultimap.Builder<ExecutableElement, AnnotationMirror> builder =\n        ImmutableListMultimap.builder();\n    for (ExecutableElement propertyMethod : propertyMethods) {\n      builder.putAll(propertyMethod, propertyFieldAnnotations(type, propertyMethod));\n    }\n    return builder.build();\n  }\n\n  private ImmutableList<AnnotationMirror> propertyFieldAnnotations(\n      TypeElement type, ExecutableElement method) {\n    // We need to exclude type annotations from the ones being output on the method, since\n    // they will be output as part of the field's type.\n    Set<String> returnTypeAnnotations =\n        getReturnTypeAnnotations(method, this::annotationAppliesToFields);\n    if (!hasAnnotationMirror(method, COPY_ANNOTATIONS_NAME)) {\n      // If there's no @CopyAnnotations, we will still copy a @Nullable annotation, if (1) it is not\n      // a TYPE_USE annotation (those appear as part of the type in the generated code) and (2) it\n      // applies to fields. All known non-TYPE_USE @Nullable annotations do apply to fields, but we\n      // check just in case.\n      return method.getAnnotationMirrors().stream()\n          .filter(\n              a -> {\n                TypeElement annotationType = asType(a.getAnnotationType().asElement());\n                return isNullable(a)\n                    && !returnTypeAnnotations.contains(annotationType.getQualifiedName().toString())\n                    && annotationAppliesToFields(annotationType);\n              })\n          .collect(toImmutableList());\n    }\n    ImmutableSet<String> excludedAnnotations =\n        ImmutableSet.<String>builder()\n            .addAll(getExcludedAnnotationClassNames(method))\n            .add(Override.class.getCanonicalName())\n            .build();\n\n    Set<String> nonFieldAnnotations =\n        method.getAnnotationMirrors().stream()\n            .map(a -> a.getAnnotationType().asElement())\n            .map(MoreElements::asType)\n            .filter(a -> !annotationAppliesToFields(a))\n            .map(e -> e.getQualifiedName().toString())\n            .collect(toSet());\n\n    Set<String> excluded =\n        ImmutableSet.<String>builder()\n            .addAll(excludedAnnotations)\n            .addAll(returnTypeAnnotations)\n            .addAll(nonFieldAnnotations)\n            .build();\n    return annotationsToCopy(type, method, excluded);\n  }\n\n  private static Set<String> getReturnTypeAnnotations(\n      ExecutableElement method, Predicate<TypeElement> typeFilter) {\n    return method.getReturnType().getAnnotationMirrors().stream()\n        .map(a -> a.getAnnotationType().asElement())\n        .map(MoreElements::asType)\n        .filter(typeFilter)\n        .map(e -> e.getQualifiedName().toString())\n        .collect(toSet());\n  }\n\n  private boolean annotationAppliesToFields(TypeElement annotation) {\n    Target target = annotation.getAnnotation(Target.class);\n    return target == null || Arrays.asList(target.value()).contains(ElementType.FIELD);\n  }\n\n  private boolean annotationVisibleFrom(AnnotationMirror annotation, Element from) {\n    Element annotationElement = annotation.getAnnotationType().asElement();\n    Visibility visibility = Visibility.effectiveVisibilityOfElement(annotationElement);\n    switch (visibility) {\n      case PUBLIC:\n        break;\n      case PROTECTED:\n        // If the annotation is protected, it must be inside another class, call it C. If our\n        // @AutoValue class is Foo then, for the annotation to be visible, either Foo must be in the\n        // same package as C or Foo must be a subclass of C. If the annotation is visible from Foo\n        // then it is also visible from our generated subclass AutoValue_Foo.\n        // The protected case only applies to method annotations. An annotation on the AutoValue_Foo\n        // class itself can't be protected, even if AutoValue_Foo ultimately inherits from the\n        // class that defines the annotation. The JLS says \"Access is permitted only within the\n        // body of a subclass\":\n        // https://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.6.2.1\n        // AutoValue_Foo is a top-level class, so an annotation on it cannot be in the body of a\n        // subclass of anything.\n        if (!getPackage(annotationElement).equals(getPackage(from))\n            && !typeUtils()\n                .isSubtype(from.asType(), annotationElement.getEnclosingElement().asType())) {\n          return false;\n        }\n        break;\n      case DEFAULT:\n        return getPackage(annotationElement).equals(getPackage(from));\n      default:\n        return false;\n    }\n    return true;\n  }\n\n  /**\n   * Returns the {@code @AutoValue} or {@code @AutoOneOf} type parameters, with a ? for every type.\n   * If we have {@code @AutoValue abstract class Foo<T extends Something>} then this method will\n   * return just {@code <?>}.\n   */\n  private static String wildcardTypeParametersString(TypeElement type) {\n    List<? extends TypeParameterElement> typeParameters = type.getTypeParameters();\n    if (typeParameters.isEmpty()) {\n      return \"\";\n    } else {\n      return typeParameters.stream().map(e -> \"?\").collect(joining(\", \", \"<\", \">\"));\n    }\n  }\n\n  // TODO(emcmanus,ronshapiro): move to auto-common\n  static Optional<AnnotationMirror> getAnnotationMirror(Element element, String annotationName) {\n    for (AnnotationMirror annotation : element.getAnnotationMirrors()) {\n      TypeElement annotationElement = MoreTypes.asTypeElement(annotation.getAnnotationType());\n      if (annotationElement.getQualifiedName().contentEquals(annotationName)) {\n        return Optional.of(annotation);\n      }\n    }\n    return Optional.empty();\n  }\n\n  static boolean hasAnnotationMirror(Element element, String annotationName) {\n    return getAnnotationMirror(element, annotationName).isPresent();\n  }\n\n  /** True if the type is a class with a non-private no-arg constructor, or is an interface. */\n  static boolean hasVisibleNoArgConstructor(TypeElement type) {\n    return type.getKind().isInterface()\n        || constructorsIn(type.getEnclosedElements()).stream()\n            .anyMatch(\n                c -> c.getParameters().isEmpty() && !c.getModifiers().contains(Modifier.PRIVATE));\n  }\n\n  final void writeSourceFile(String className, String text, TypeElement originatingType) {\n    try {\n      JavaFileObject sourceFile =\n          processingEnv.getFiler().createSourceFile(className, originatingType);\n      try (Writer writer = sourceFile.openWriter()) {\n        writer.write(text);\n      }\n    } catch (IOException e) {\n      // This should really be an error, but we make it a warning in the hope of resisting Eclipse\n      // bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=367599. If that bug manifests, we may get\n      // invoked more than once for the same file, so ignoring the ability to overwrite it is the\n      // right thing to do. If we are unable to write for some other reason, we should get a compile\n      // error later because user code will have a reference to the code we were supposed to\n      // generate (new AutoValue_Foo() or whatever) and that reference will be undefined.\n      errorReporter.reportWarning(\n          originatingType,\n          \"[AutoValueCouldNotWrite] Could not write generated class %s: %s\",\n          className,\n          e);\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/AutoValueishTemplateVars.java",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport com.google.common.collect.ImmutableList;\n\n/**\n * The variables to substitute into the autovalue.vm, autooneof.vm, or builder.vm templates.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@SuppressWarnings(\"unused\") // the fields in this class are only read via reflection\nabstract class AutoValueishTemplateVars extends TemplateVars {\n  /** Whether to generate an equals(Object) method. */\n  Boolean equals;\n\n  /** Whether to generate a hashCode() method. */\n  Boolean hashCode;\n\n  /** Whether to generate a toString() method. */\n  Boolean toString;\n\n  /**\n   * A string representing the parameter type declaration of the equals(Object) method, including\n   * any annotations. If {@link #equals} is false, this field is ignored (but it must still be\n   * non-null).\n   */\n  String equalsParameterType;\n\n  /** The encoding of the {@code Generated} class. Empty if the class is not available. */\n  String generated;\n\n  /** The package of the class with the {@code @AutoValue} annotation and its generated subclass. */\n  String pkg;\n\n  /**\n   * The name of the class with the {@code @AutoValue} annotation, including containing classes but\n   * not including the package name.\n   */\n  String origClass;\n\n  /** The simple name of the class with the {@code @AutoValue} annotation. */\n  String simpleClassName;\n\n  /**\n   * The full spelling of any annotations to add to this class, or an empty list if there are none.\n   * A non-empty value might look something like {@code\n   * \"@`com.google.common.annotations.GwtCompatible`(serializable = true)\"}. The {@code ``} marks\n   * are explained in {@link TypeEncoder}.\n   */\n  ImmutableList<String> annotations;\n\n  /**\n   * The formal generic signature of the class with the {@code @AutoValue} or {@code AutoOneOf}\n   * annotation and any generated subclass. This is empty, or contains type variables with optional\n   * bounds, for example {@code <K, V extends K>}.\n   */\n  String formalTypes;\n\n  /**\n   * The generic signature used by any generated subclass for its superclass reference. This is\n   * empty, or contains only type variables with no bounds, for example {@code <K, V>}.\n   */\n  String actualTypes;\n\n  /**\n   * The generic signature in {@link #actualTypes} where every variable has been replaced by a\n   * wildcard, for example {@code <?, ?>}.\n   */\n  String wildcardTypes;\n\n  /**\n   * The text of the complete serialVersionUID declaration, or empty if there is none. When\n   * non-empty, it will be something like {@code private static final long serialVersionUID =\n   * 123L;}.\n   */\n  String serialVersionUID;\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/BuilderMethodClassifier.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.auto.value.processor.AutoValueishProcessor.nullableAnnotationFor;\n\nimport com.google.auto.common.MoreElements;\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.value.processor.BuilderSpec.Copier;\nimport com.google.auto.value.processor.BuilderSpec.PropertySetter;\nimport com.google.auto.value.processor.PropertyBuilderClassifier.PropertyBuilder;\nimport com.google.common.base.Equivalence;\nimport com.google.common.collect.ImmutableBiMap;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableMultimap;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Iterables;\nimport com.google.common.collect.LinkedListMultimap;\nimport com.google.common.collect.Multimap;\nimport java.util.LinkedHashMap;\nimport java.util.LinkedHashSet;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.Set;\nimport java.util.function.Function;\nimport java.util.stream.Stream;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.Modifier;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.ElementFilter;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.Types;\n\n/**\n * Classifies methods inside builder types, based on their names and parameter and return types.\n *\n * @param <E> the kind of {@link Element} that the corresponding properties are defined by. This is\n *     {@link ExecutableElement} for AutoValue, where properties are defined by abstract methods,\n *     and {@link VariableElement} for AutoBuilder, where they are defined by constructor or method\n *     parameters.\n * @author Éamonn McManus\n */\nabstract class BuilderMethodClassifier<E extends Element> {\n  private static final Equivalence<TypeMirror> TYPE_EQUIVALENCE = MoreTypes.equivalence();\n\n  private final ErrorReporter errorReporter;\n  private final Types typeUtils;\n  private final Elements elementUtils;\n  private final TypeMirror builtType;\n  private final TypeElement builderType;\n  private final ImmutableSet<String> propertiesWithDefaults;\n\n  /**\n   * Property types, rewritten to refer to type variables in the builder. For example, suppose you\n   * have {@code @AutoValue abstract class Foo<T>} with a getter {@code abstract T bar()} and a\n   * builder {@code @AutoValue.Builder interface Builder<T>} with a setter {@code abstract\n   * Builder<T> setBar(T t)}. Then the {@code T} of {@code Foo<T>} and the {@code T} of {@code\n   * Foo.Builder<T>} are two separate variables. Originally {@code bar()} returned the {@code T} of\n   * {@code Foo<T>}, but in this map we have rewritten it to be the {@code T} of {@code\n   * Foo.Builder<T>}.\n   */\n  private final ImmutableMap<String, AnnotatedTypeMirror> rewrittenPropertyTypes;\n\n  private final Set<ExecutableElement> buildMethods = new LinkedHashSet<>();\n  private final Map<String, BuilderSpec.PropertyGetter> builderGetters = new LinkedHashMap<>();\n  private final Map<String, PropertyBuilder> propertyNameToPropertyBuilder = new LinkedHashMap<>();\n  private final Multimap<String, PropertySetter> propertyNameToPrefixedSetters =\n      LinkedListMultimap.create();\n  private final Multimap<String, PropertySetter> propertyNameToUnprefixedSetters =\n      LinkedListMultimap.create();\n  private final Nullables nullables;\n\n  private boolean settersPrefixed;\n\n  BuilderMethodClassifier(\n      ErrorReporter errorReporter,\n      ProcessingEnvironment processingEnv,\n      TypeMirror builtType,\n      TypeElement builderType,\n      ImmutableMap<String, AnnotatedTypeMirror> rewrittenPropertyTypes,\n      ImmutableSet<String> propertiesWithDefaults,\n      Nullables nullables) {\n    this.errorReporter = errorReporter;\n    this.typeUtils = processingEnv.getTypeUtils();\n    this.elementUtils = processingEnv.getElementUtils();\n    this.builtType = builtType;\n    this.builderType = builderType;\n    this.rewrittenPropertyTypes = rewrittenPropertyTypes;\n    this.propertiesWithDefaults = propertiesWithDefaults;\n    this.nullables = nullables;\n  }\n\n  /**\n   * Returns a multimap from the name of a property to the methods that set it. If the property is\n   * defined by an abstract method in the {@code @AutoValue} class called {@code foo()} or {@code\n   * getFoo()} then the name of the property is {@code foo} and there will be an entry in the map\n   * where the key is {@code \"foo\"} and the value describes a method in the builder called {@code\n   * foo} or {@code setFoo}.\n   */\n  ImmutableMultimap<String, PropertySetter> propertyNameToSetters() {\n    return ImmutableMultimap.copyOf(\n        settersPrefixed ? propertyNameToPrefixedSetters : propertyNameToUnprefixedSetters);\n  }\n\n  Map<String, PropertyBuilder> propertyNameToPropertyBuilder() {\n    return propertyNameToPropertyBuilder;\n  }\n\n  /**\n   * Returns the set of properties that have getters in the builder. If a property is defined by an\n   * abstract method in the {@code @AutoValue} class called {@code foo()} or {@code getFoo()} then\n   * the name of the property is {@code foo}, If the builder also has a method of the same name\n   * ({@code foo()} or {@code getFoo()}) then the set returned here will contain {@code foo}.\n   */\n  ImmutableMap<String, BuilderSpec.PropertyGetter> builderGetters() {\n    return ImmutableMap.copyOf(builderGetters);\n  }\n\n  /**\n   * Returns the methods that were identified as {@code build()} methods. These are methods that\n   * have no parameters and return the {@code @AutoValue} type, conventionally called {@code\n   * build()}.\n   */\n  Set<ExecutableElement> buildMethods() {\n    return ImmutableSet.copyOf(buildMethods);\n  }\n\n  /** Classifies the given methods and sets the state of this object based on what is found. */\n  boolean classifyMethods(Iterable<ExecutableElement> methods, boolean autoValueHasToBuilder) {\n    int startErrorCount = errorReporter.errorCount();\n    for (ExecutableElement method : methods) {\n      classifyMethod(method);\n    }\n    if (errorReporter.errorCount() > startErrorCount) {\n      return false;\n    }\n    Multimap<String, PropertySetter> propertyNameToSetter;\n    if (propertyNameToPrefixedSetters.isEmpty()) {\n      propertyNameToSetter = propertyNameToUnprefixedSetters;\n      this.settersPrefixed = false;\n    } else if (propertyNameToUnprefixedSetters.isEmpty()) {\n      propertyNameToSetter = propertyNameToPrefixedSetters;\n      this.settersPrefixed = true;\n    } else {\n      errorReporter.reportError(\n          propertyNameToUnprefixedSetters.values().iterator().next().getSetter(),\n          \"[%sSetNotSet] If any setter methods use the setFoo convention then all must\",\n          autoWhat());\n      return false;\n    }\n    for (String property : rewrittenPropertyTypes.keySet()) {\n      TypeMirror propertyType = rewrittenPropertyTypes.get(property).getType();\n      boolean hasSetter = propertyNameToSetter.containsKey(property);\n      PropertyBuilder propertyBuilder = propertyNameToPropertyBuilder.get(property);\n      boolean hasBuilder = propertyBuilder != null;\n      if (hasBuilder) {\n        // If property bar of type Bar has a barBuilder() that returns BarBuilder, then it must\n        // be possible to make a BarBuilder from a Bar if either (1) the @AutoValue class has a\n        // toBuilder() or (2) there is also a setBar(Bar). Making BarBuilder from Bar is\n        // possible if Bar either has a toBuilder() method or BarBuilder has an addAll or putAll\n        // method that accepts a Bar argument.\n        boolean canMakeBarBuilder =\n            (propertyBuilder.getBuiltToBuilder() != null || propertyBuilder.getCopyAll() != null);\n        boolean needToMakeBarBuilder = (autoValueHasToBuilder || hasSetter);\n        if (needToMakeBarBuilder && !canMakeBarBuilder) {\n          errorReporter.reportError(\n              propertyBuilder.getPropertyBuilderMethod(),\n              \"[AutoValueCantMakeBuilder] Property builder method returns %1$s but there is no\"\n                  + \" way to make that type from %2$s: %2$s does not have a non-static\"\n                  + \" toBuilder() method that returns %1$s, and %1$s does not have a method\"\n                  + \" addAll or putAll that accepts an argument of type %2$s\",\n              propertyBuilder.getBuilderTypeMirror(),\n              propertyType);\n        }\n      } else if (!hasSetter && !propertiesWithDefaults.contains(property)) {\n        // We have neither barBuilder() nor setBar(Bar), so we should complain.\n        String setterName = settersPrefixed ? prefixWithSet(property) : property;\n        errorReporter.reportError(\n            builderType,\n            \"[%sBuilderMissingMethod] Expected a method with this signature: %s\"\n                + \" %s(%s), or a %sBuilder() method\",\n            autoWhat(),\n            builderType.asType(),\n            setterName,\n            propertyType,\n            property);\n      }\n    }\n    return errorReporter.errorCount() == startErrorCount;\n  }\n\n  /** Classifies a method and update the state of this object based on what is found. */\n  private void classifyMethod(ExecutableElement method) {\n    switch (method.getParameters().size()) {\n      case 0:\n        classifyMethodNoArgs(method);\n        break;\n      case 1:\n        classifyMethodOneArg(method);\n        break;\n      default:\n        errorReporter.reportError(\n            method, \"[%sBuilderArgs] Builder methods must have 0 or 1 parameters\", autoWhat());\n    }\n  }\n\n  /**\n   * Classifies a method given that it has no arguments. Currently a method with no arguments can be\n   * a {@code build()} method, meaning that its return type must be the {@code @AutoValue} class; it\n   * can be a getter, with the same signature as one of the property getters in the\n   * {@code @AutoValue} class; or it can be a property builder, like {@code\n   * ImmutableList.Builder<String> foosBuilder()} for the property defined by {@code\n   * ImmutableList<String> foos()} or {@code getFoos()}.\n   */\n  private void classifyMethodNoArgs(ExecutableElement method) {\n    Optional<String> getterProperty = propertyForBuilderGetter(method);\n    if (getterProperty.isPresent()) {\n      classifyGetter(method, getterProperty.get());\n      return;\n    }\n\n    String methodName = method.getSimpleName().toString();\n    TypeMirror returnType = builderMethodReturnType(method).getType();\n\n    if (methodName.endsWith(\"Builder\")) {\n      String prefix = methodName.substring(0, methodName.length() - \"Builder\".length());\n      String property =\n          rewrittenPropertyTypes.containsKey(prefix)\n              ? prefix\n              : rewrittenPropertyTypes.keySet().stream()\n                  .filter(p -> PropertyNames.decapitalizeNormally(p).equals(prefix))\n                  .findFirst()\n                  .orElse(null);\n      if (property != null) {\n        PropertyBuilderClassifier propertyBuilderClassifier =\n            new PropertyBuilderClassifier(\n                errorReporter,\n                typeUtils,\n                elementUtils,\n                this,\n                this::propertyIsNullable,\n                rewrittenPropertyTypes,\n                nullables);\n        Optional<PropertyBuilder> propertyBuilder =\n            propertyBuilderClassifier.makePropertyBuilder(method, property);\n        if (propertyBuilder.isPresent()) {\n          propertyNameToPropertyBuilder.put(property, propertyBuilder.get());\n        }\n        return;\n      }\n    }\n\n    if (TYPE_EQUIVALENCE.equivalent(returnType, builtType)) {\n      buildMethods.add(method);\n    } else {\n      errorReporter.reportError(\n          method,\n          \"[%1$sBuilderNoArg] Method without arguments should be a build method returning\"\n              + \" %2$s, or a getter method with the same name and type as %3$s,\"\n              + \" or fooBuilder() where %4$s is %3$s\",\n          // \"where foo() or getFoo() is a method in...\" or \"where foo is a parameter of...\"\n          autoWhat(),\n          builtType,\n          getterMustMatch(),\n          fooBuilderMustMatch());\n    }\n  }\n\n  private void classifyGetter(ExecutableElement builderGetter, String propertyName) {\n    TypeMirror originalGetterType = rewrittenPropertyTypes.get(propertyName).getType();\n    AnnotatedTypeMirror builderGetterType = builderMethodReturnType(builderGetter);\n    String builderGetterTypeString = TypeEncoder.encodeWithAnnotations(builderGetterType);\n    if (TYPE_EQUIVALENCE.equivalent(builderGetterType.getType(), originalGetterType)) {\n      builderGetters.put(\n          propertyName,\n          new BuilderSpec.PropertyGetter(builderGetter, builderGetterTypeString, null));\n      return;\n    }\n    Optionalish optional = Optionalish.createIfOptional(builderGetterType.getType());\n    if (optional != null) {\n      TypeMirror containedType = optional.getContainedType(typeUtils);\n      // If the original method is int getFoo() then we allow Optional<Integer> here.\n      // boxedOriginalType is Integer, and containedType is also Integer.\n      // We don't need any special code for OptionalInt because containedType will be int then.\n      TypeMirror boxedOriginalType =\n          originalGetterType.getKind().isPrimitive()\n              ? typeUtils.boxedClass(MoreTypes.asPrimitiveType(originalGetterType)).asType()\n              : null;\n      if (TYPE_EQUIVALENCE.equivalent(containedType, originalGetterType)\n          || TYPE_EQUIVALENCE.equivalent(containedType, boxedOriginalType)) {\n        builderGetters.put(\n            propertyName,\n            new BuilderSpec.PropertyGetter(builderGetter, builderGetterTypeString, optional));\n        return;\n      }\n    }\n    errorReporter.reportError(\n        builderGetter,\n        \"[AutoValueBuilderReturnType] Method matches a property of %1$s but has return type %2$s\"\n            + \" instead of %3$s or an Optional wrapping of %3$s\",\n        builtType,\n        builderGetterType,\n        originalGetterType);\n  }\n\n  /**\n   * Classifies a method given that it has one argument. A method with one argument can be:\n   *\n   * <ul>\n   *   <li>a setter, meaning that it looks like {@code foo(T)} or {@code setFoo(T)}, where the\n   *       {@code AutoValue} class has a property called {@code foo} of type {@code T};\n   *   <li>a property builder with one argument, meaning it looks like {@code\n   *       ImmutableSortedSet.Builder<V> foosBuilder(Comparator<V>)}, where the {@code AutoValue}\n   *       class has a property called {@code foos} with a type whose builder can be made with an\n   *       argument of the given type.\n   * </ul>\n   */\n  private void classifyMethodOneArg(ExecutableElement method) {\n    if (classifyPropertyBuilderOneArg(method)) {\n      return;\n    }\n    String methodName = method.getSimpleName().toString();\n    ImmutableMap<String, E> propertyElements = propertyElements();\n    String propertyName = null;\n    E propertyElement = propertyElements.get(methodName);\n    Multimap<String, PropertySetter> propertyNameToSetters = null;\n    if (propertyElement != null) {\n      propertyNameToSetters = propertyNameToUnprefixedSetters;\n      propertyName = methodName;\n    } else if (methodName.startsWith(\"set\") && methodName.length() > 3) {\n      propertyNameToSetters = propertyNameToPrefixedSetters;\n      propertyName = PropertyNames.decapitalizeLikeJavaBeans(methodName.substring(3));\n      propertyElement = propertyElements.get(propertyName);\n      if (propertyElement == null) {\n        // If our property is defined by a getter called getOAuth() then it is called \"OAuth\"\n        // because of JavaBeans rules. Therefore we want JavaBeans rules to be used for the setter\n        // too, so that you can write setOAuth(x). Meanwhile if the property is defined by a getter\n        // called oAuth() then it is called \"oAuth\", but you would still expect to be able to set it\n        // using setOAuth(x). Hence the second try using a decapitalize method without the quirky\n        // two-leading-capitals rule.\n        propertyName = PropertyNames.decapitalizeNormally(methodName.substring(3));\n        propertyElement = propertyElements.get(propertyName);\n      }\n    } else {\n      // We might also have an unprefixed setter, so the getter is called OAuth() or getOAuth() and\n      // the setter is called oAuth(x), where again JavaBeans rules imply that it should be called\n      // OAuth(x). Iterating over the properties here is a bit clunky but this case should be\n      // unusual.\n      propertyNameToSetters = propertyNameToUnprefixedSetters;\n      for (Map.Entry<String, E> entry : propertyElements.entrySet()) {\n        if (methodName.equals(PropertyNames.decapitalizeNormally(entry.getKey()))) {\n          propertyName = entry.getKey();\n          propertyElement = entry.getValue();\n          break;\n        }\n      }\n    }\n    if (propertyElement == null || propertyNameToSetters == null) {\n      // The second disjunct isn't needed but convinces control-flow checkers that\n      // propertyNameToSetters can't be null when we call put on it below.\n      errorReporter.reportError(\n          method,\n          \"[%sBuilderWhatProp] Method %s does not correspond to %s\",\n          autoWhat(),\n          methodName,\n          getterMustMatch());\n      checkForFailedJavaBean(method);\n      return;\n    }\n    Optional<Copier> function = getSetterFunction(propertyElement, method);\n    if (function.isPresent()) {\n      MethodSignature methodSignature = MethodSignature.asMemberOf(typeUtils, builderType, method);\n      TypeMirror returnType = methodSignature.returnType().getType();\n      if (typeUtils.isSubtype(builderType.asType(), returnType)\n          && !MoreTypes.isTypeOf(Object.class, returnType)) {\n        if (nullableAnnotationFor(method, returnType).isPresent()) {\n          errorReporter.\n              reportWarning(\n              method,\n              \"[%sBuilderSetterNullable] Setter methods always return the Builder so @Nullable\"\n                  + \" is not appropriate\",\n              autoWhat());\n        }\n        // We allow the return type to be a supertype (other than Object), to support step builders.\n        AnnotatedTypeMirror parameterType =\n            Iterables.getOnlyElement(methodSignature.parameterTypes());\n        propertyNameToSetters.put(\n            propertyName, new PropertySetter(method, parameterType, function.get()));\n      } else {\n        errorReporter.reportError(\n            method,\n            \"[%sBuilderRet] Setter methods must return %s or a supertype\",\n            autoWhat(),\n            builderType.asType());\n      }\n    }\n  }\n\n  /**\n   * Classifies a method given that it has one argument and is a property builder with a parameter,\n   * like {@code ImmutableSortedSet.Builder<String> foosBuilder(Comparator<String>)}.\n   *\n   * @param method A method to classify\n   * @return true if method has been classified successfully\n   */\n  private boolean classifyPropertyBuilderOneArg(ExecutableElement method) {\n    String methodName = method.getSimpleName().toString();\n    if (!methodName.endsWith(\"Builder\")) {\n      return false;\n    }\n    String property = methodName.substring(0, methodName.length() - \"Builder\".length());\n    if (!rewrittenPropertyTypes.containsKey(property)) {\n      return false;\n    }\n    PropertyBuilderClassifier propertyBuilderClassifier =\n        new PropertyBuilderClassifier(\n            errorReporter,\n            typeUtils,\n            elementUtils,\n            this,\n            this::propertyIsNullable,\n            rewrittenPropertyTypes,\n            nullables);\n    Optional<PropertyBuilder> maybePropertyBuilder =\n        propertyBuilderClassifier.makePropertyBuilder(method, property);\n    maybePropertyBuilder.ifPresent(\n        propertyBuilder -> propertyNameToPropertyBuilder.put(property, propertyBuilder));\n    return maybePropertyBuilder.isPresent();\n  }\n\n  /**\n   * Returns an {@code Optional} describing how to convert a value from the setter's parameter type\n   * to the getter's return type, or {@code Optional.empty()} if the conversion isn't possible. An\n   * error will have been reported in the latter case. We can convert if they are already the same\n   * type, when the returned function will be the identity; or if the setter type can be copied\n   * using a method like {@code ImmutableList.copyOf} or {@code Optional.of}, when the returned\n   * function will be something like {@code s -> \"Optional.of(\" + s + \")\"}.\n   */\n  private Optional<Copier> getSetterFunction(E propertyElement, ExecutableElement setter) {\n    VariableElement parameterElement = Iterables.getOnlyElement(setter.getParameters());\n    boolean nullableParameter =\n        nullableAnnotationFor(parameterElement, parameterElement.asType()).isPresent();\n    String property = propertyElements().inverse().get(propertyElement);\n    TypeMirror targetType = rewrittenPropertyTypes.get(property).getType();\n    TypeMirror parameterType =\n        MethodSignature.asMemberOf(typeUtils, builderType, setter)\n            .parameterTypes()\n            .get(0)\n            .getType();\n    // Two types are assignable to each other if they are the same type, or if one is primitive and\n    // the other is the corresponding boxed type. There might be other cases where this is true, but\n    // we're likely to want to accept those too.\n    if (typeUtils.isAssignable(parameterType, targetType)\n        && typeUtils.isAssignable(targetType, parameterType)) {\n      if (nullableParameter) {\n        boolean nullableProperty =\n            nullableAnnotationFor(propertyElement, originalPropertyType(propertyElement))\n                .isPresent();\n        if (!nullableProperty) {\n          errorReporter.reportError(\n              setter,\n              \"[%sNullNotNull] Parameter of setter method is @Nullable but %s is not\",\n              autoWhat(),\n              propertyString(propertyElement));\n          return Optional.empty();\n        }\n      }\n      if (!parameterElement.asType().getKind().isPrimitive()\n          && originalPropertyType(propertyElement).getKind().isPrimitive()) {\n        errorReporter\n            .reportWarning(\n            setter,\n            \"[%sUnnecessaryBoxing] %s is primitive but parameter of setter method is not\",\n            autoWhat(),\n            propertyString(propertyElement));\n      }\n      return Optional.of(Copier.IDENTITY);\n    }\n\n    // Parameter type is not equal to property type, but might be convertible with copyOf.\n    ImmutableList<ExecutableElement> copyOfMethods = copyOfMethods(targetType, nullableParameter);\n    if (!copyOfMethods.isEmpty()) {\n      return getConvertingSetterFunction(copyOfMethods, propertyElement, setter, parameterType);\n    }\n    errorReporter.reportError(\n        setter,\n        \"[%sGetVsSet] Parameter type %s of setter method should be %s to match %s\",\n        autoWhat(),\n        parameterType,\n        targetType,\n        propertyString(propertyElement));\n    return Optional.empty();\n  }\n\n  /**\n   * Returns an {@code Optional} describing how to convert a value from the setter's parameter type\n   * to the getter's return type using one of the given methods, or {@code Optional.empty()} if the\n   * conversion isn't possible. An error will have been reported in the latter case.\n   */\n  private Optional<Copier> getConvertingSetterFunction(\n      ImmutableList<ExecutableElement> copyOfMethods,\n      E propertyElement,\n      ExecutableElement setter,\n      TypeMirror parameterType) {\n    String property = propertyElements().inverse().get(propertyElement);\n    DeclaredType targetType = MoreTypes.asDeclared(rewrittenPropertyTypes.get(property).getType());\n    for (ExecutableElement copyOfMethod : copyOfMethods) {\n      Optional<Copier> function =\n          getConvertingSetterFunction(copyOfMethod, targetType, parameterType);\n      if (function.isPresent()) {\n        return function;\n      }\n    }\n    String targetTypeSimpleName = targetType.asElement().getSimpleName().toString();\n    errorReporter.reportError(\n        setter,\n        \"[%sGetVsSetOrConvert] Parameter type %s of setter method should be %s to match %s, or it\"\n            + \" should be a type that can be passed to %s.%s to produce %s\",\n        autoWhat(),\n        parameterType,\n        targetType,\n        propertyString(propertyElement),\n        targetTypeSimpleName,\n        copyOfMethods.get(0).getSimpleName(),\n        targetType);\n    return Optional.empty();\n  }\n\n  /**\n   * Returns an {@code Optional} containing a function to use {@code copyOfMethod} to copy the\n   * {@code parameterType} to the {@code targetType}, or {@code Optional.empty()} if the method\n   * can't be used. For example, we might have a property of type {@code ImmutableSet<T>} and our\n   * setter has a parameter of type {@code Set<? extends T>}. Can we use {@code ImmutableSet<E>\n   * ImmutableSet.copyOf(Collection<? extends E>)} to set the property? What about {@code\n   * ImmutableSet<E> ImmutableSet.copyOf(E[])}?\n   *\n   * <p>The example here is deliberately complicated, in that it has a type parameter of its own,\n   * presumably because the {@code @AutoValue} class is {@code Foo<T>}. One subtle point is that the\n   * builder will then be {@code Builder<T>} where this {@code T} is a <i>different</i> type\n   * variable. However, we've used {@link TypeVariables} to ensure that the {@code T} in {@code\n   * ImmutableSet<T>} is actually the one from {@code Builder<T>} instead of the original one from\n   * {@code Foo<T>}.}\n   *\n   * @param copyOfMethod the candidate method to do the copy, {@code\n   *     ImmutableSet.copyOf(Collection<? extends E>)} or {@code ImmutableSet.copyOf(E[])} in the\n   *     examples.\n   * @param targetType the type of the property to be set, {@code ImmutableSet<T>} in the example.\n   * @param parameterType the type of the setter parameter, {@code Set<? extends T>} in the example.\n   * @return a function that maps a string parameter to a method call using that parameter. For\n   *     example it might map {@code foo} to {@code ImmutableList.copyOf(foo)}.\n   */\n  private Optional<Copier> getConvertingSetterFunction(\n      ExecutableElement copyOfMethod, DeclaredType targetType, TypeMirror parameterType) {\n    // We have a parameter type, for example Set<? extends T>, and we want to know if it can be\n    // passed to the given copyOf method, which might for example be one of these methods from\n    // ImmutableSet:\n    //    public static <E> ImmutableSet<E> copyOf(Collection<? extends E> elements)\n    //    public static <E> ImmutableSet<E> copyOf(E[] elements)\n    // Additionally, if it can indeed be passed to the method, we want to know whether the result\n    // (here ImmutableSet<? extends T>) is compatible with the property to be set.\n    // We can't use Types.asMemberOf to do the substitution for us, because the methods in question\n    // are static. So even if our target type is ImmutableSet<String>, if we ask what the type of\n    // copyOf is in ImmutableSet<String> it will still tell us <T> Optional<T> (T).\n    // Instead, we do the variable substitutions ourselves.\n    if (TypeVariables.canAssignStaticMethodResult(\n        copyOfMethod, parameterType, targetType, typeUtils)) {\n      String method = TypeEncoder.encodeRaw(targetType) + \".\" + copyOfMethod.getSimpleName();\n      Function<String, String> callMethod = s -> method + \"(\" + s + \")\";\n      // This is a big old hack. We guess that the method can accept a null parameter if it has\n      // \"Nullable\" in the name, which java.util.Optional.ofNullable and\n      // com.google.common.base.Optional.fromNullable do.\n      Copier copier =\n          method.contains(\"Nullable\")\n              ? Copier.acceptingNull(callMethod)\n              : Copier.notAcceptingNull(callMethod);\n      return Optional.of(copier);\n    }\n    return Optional.empty();\n  }\n\n  /**\n   * Returns {@code copyOf} methods from the given type. These are static methods with a single\n   * parameter, called {@code copyOf} or {@code copyOfSorted} for Guava collection types, and called\n   * {@code of} or {@code ofNullable} for {@code Optional}. All of Guava's concrete immutable\n   * collection types have at least one such method, but we will also accept other classes with an\n   * appropriate {@code copyOf} method, such as {@link java.util.EnumSet}.\n   */\n  private ImmutableList<ExecutableElement> copyOfMethods(\n      TypeMirror targetType, boolean nullableParameter) {\n    if (!targetType.getKind().equals(TypeKind.DECLARED)) {\n      return ImmutableList.of();\n    }\n    ImmutableSet<String> copyOfNames;\n    Optionalish optionalish = Optionalish.createIfOptional(targetType);\n    if (optionalish == null) {\n      copyOfNames = ImmutableSet.of(\"copyOfSorted\", \"copyOf\");\n    } else {\n      copyOfNames = ImmutableSet.of(nullableParameter ? optionalish.ofNullable() : \"of\");\n    }\n    TypeElement targetTypeElement = MoreElements.asType(typeUtils.asElement(targetType));\n    ImmutableList.Builder<ExecutableElement> copyOfMethods = ImmutableList.builder();\n    for (String copyOfName : copyOfNames) {\n      for (ExecutableElement method :\n          ElementFilter.methodsIn(targetTypeElement.getEnclosedElements())) {\n        if (method.getSimpleName().contentEquals(copyOfName)\n            && method.getParameters().size() == 1\n            && method.getModifiers().contains(Modifier.STATIC)) {\n          copyOfMethods.add(method);\n        }\n      }\n    }\n    return copyOfMethods.build();\n  }\n\n  /**\n   * Returns the return type of the given method from the builder. This should be the final type of\n   * the method when any bound type variables are substituted. Consider this example:\n   *\n   * <pre>{@code\n   * abstract static class ParentBuilder<B extends ParentBuilder> {\n   *   B setFoo(String s);\n   * }\n   * abstract static class ChildBuilder extends ParentBuilder<ChildBuilder> {\n   *   ...\n   * }\n   * }</pre>\n   *\n   * If the builder is {@code ChildBuilder} then the return type of {@code setFoo} is also {@code\n   * ChildBuilder}, and not {@code B} as its {@code getReturnType()} method would claim.\n   */\n  AnnotatedTypeMirror builderMethodReturnType(ExecutableElement builderMethod) {\n    return MethodSignature.asMemberOf(typeUtils, builderType, builderMethod).returnType();\n  }\n\n  private static String prefixWithSet(String propertyName) {\n    // This is not internationalizationally correct, but it corresponds to what\n    // Introspector.decapitalize does.\n    return \"set\" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);\n  }\n\n  /**\n   * True if the given property is nullable, either because its type has a {@code @Nullable} type\n   * annotation, or because its getter method has a {@code @Nullable} method annotation.\n   */\n  private boolean propertyIsNullable(String property) {\n    E propertyElement = propertyElements().get(property);\n    return Stream.of(propertyElement, originalPropertyType(propertyElement))\n        .flatMap(ac -> ac.getAnnotationMirrors().stream())\n        .map(a -> a.getAnnotationType().asElement().getSimpleName())\n        .anyMatch(n -> n.contentEquals(\"Nullable\"));\n  }\n\n  /**\n   * Returns a map from property names to the corresponding source program elements. For AutoValue,\n   * these elements are the abstract getter methods in the {@code @AutoValue} class. For\n   * AutoBuilder, they are the parameters of the constructor or method that the generated builder\n   * will call.\n   */\n  abstract ImmutableBiMap<String, E> propertyElements();\n\n  /**\n   * Returns the property type as it appears on the original source program element. This can be\n   * different from the type stored in {@link #rewrittenPropertyTypes} since that one will refer to\n   * type variables in the builder rather than in the original class.\n   */\n  abstract TypeMirror originalPropertyType(E propertyElement);\n\n  /**\n   * A string identifying the given property element, which is a method for AutoValue or a parameter\n   * for AutoBuilder.\n   */\n  abstract String propertyString(E propertyElement);\n\n  /**\n   * Returns the name of the property that the given no-arg builder method queries, if any. For\n   * example, if your {@code @AutoValue} class has a method {@code abstract String getBar()} then an\n   * abstract method in its builder with the same signature will query the {@code bar} property.\n   */\n  abstract Optional<String> propertyForBuilderGetter(ExecutableElement method);\n\n  /**\n   * Checks for failed JavaBean usage when a method that looks like a setter doesn't actually match\n   * anything, and emits a compiler Note if detected. A frequent source of problems is where the\n   * JavaBeans conventions have been followed for most but not all getters. Then AutoValue considers\n   * that they haven't been followed at all, so you might have a property called getFoo where you\n   * thought it was called just foo, and you might not understand why your setter called setFoo is\n   * rejected (it would have to be called setGetFoo).\n   *\n   * <p>This is not relevant for AutoBuilder, which uses parameter names rather than getters. The\n   * parameter names are unambiguously the same as the property names.\n   */\n  abstract void checkForFailedJavaBean(ExecutableElement rejectedSetter);\n\n  /**\n   * A string describing what sort of Auto this is, {@code \"AutoValue\"} or {@code \"AutoBuilder\"}.\n   */\n  abstract String autoWhat();\n\n  /**\n   * A string describing what a builder getter must match: a property method for AutoValue, a\n   * parameter for AutoBuilder.\n   */\n  abstract String getterMustMatch();\n\n  /**\n   * A string describing what a property builder for property {@code foo} must match, {@code foo()\n   * or getFoo()} for AutoValue, {@code foo} for AutoBuilder.\n   */\n  abstract String fooBuilderMustMatch();\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/BuilderMethodClassifierForAutoBuilder.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.collect.ImmutableBiMap.toImmutableBiMap;\nimport static com.google.common.collect.ImmutableMap.toImmutableMap;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.common.base.Equivalence;\nimport com.google.common.collect.ImmutableBiMap;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.function.Function;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.TypeParameterElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.type.TypeVariable;\nimport javax.lang.model.util.Types;\n\nclass BuilderMethodClassifierForAutoBuilder extends BuilderMethodClassifier<VariableElement> {\n  private final Executable executable;\n  private final ImmutableBiMap<VariableElement, String> paramToPropertyName;\n\n  private BuilderMethodClassifierForAutoBuilder(\n      ErrorReporter errorReporter,\n      ProcessingEnvironment processingEnv,\n      Executable executable,\n      TypeMirror builtType,\n      TypeElement builderType,\n      ImmutableBiMap<VariableElement, String> paramToPropertyName,\n      ImmutableMap<String, AnnotatedTypeMirror> rewrittenPropertyTypes,\n      ImmutableSet<String> propertiesWithDefaults,\n      Nullables nullables) {\n    super(\n        errorReporter,\n        processingEnv,\n        builtType,\n        builderType,\n        rewrittenPropertyTypes,\n        propertiesWithDefaults,\n        nullables);\n    this.executable = executable;\n    this.paramToPropertyName = paramToPropertyName;\n  }\n\n  /**\n   * Classifies the given methods from a builder type and its ancestors.\n   *\n   * @param methods the abstract methods in {@code builderType} and its ancestors.\n   * @param errorReporter where to report errors.\n   * @param processingEnv the ProcessingEnvironment for annotation processing.\n   * @param executable the constructor or static method that AutoBuilder will call.\n   * @param builtType the type to be built.\n   * @param builderType the builder class or interface within {@code ofClass}.\n   * @param propertiesWithDefaults properties that have a default value, so it is not an error for\n   *     them not to have a setter.\n   * @return an {@code Optional} that contains the results of the classification if it was\n   *     successful or nothing if it was not.\n   */\n  static Optional<BuilderMethodClassifier<VariableElement>> classify(\n      Iterable<ExecutableElement> methods,\n      ErrorReporter errorReporter,\n      ProcessingEnvironment processingEnv,\n      Executable executable,\n      TypeMirror builtType,\n      TypeElement builderType,\n      ImmutableSet<String> propertiesWithDefaults,\n      Nullables nullables) {\n    ImmutableBiMap<VariableElement, String> paramToPropertyName =\n        executable.parameters().stream()\n            .collect(toImmutableBiMap(v -> v, v -> v.getSimpleName().toString()));\n    ImmutableMap<String, AnnotatedTypeMirror> rewrittenPropertyTypes =\n        rewriteParameterTypes(executable, builderType, errorReporter, processingEnv.getTypeUtils());\n    BuilderMethodClassifier<VariableElement> classifier =\n        new BuilderMethodClassifierForAutoBuilder(\n            errorReporter,\n            processingEnv,\n            executable,\n            builtType,\n            builderType,\n            paramToPropertyName,\n            rewrittenPropertyTypes,\n            propertiesWithDefaults,\n            nullables);\n    if (classifier.classifyMethods(methods, false)) {\n      return Optional.of(classifier);\n    } else {\n      return Optional.empty();\n    }\n  }\n\n  // Rewrites the parameter types of the executable so they use the type variables of the builder\n  // where appropriate.\n  //\n  // Suppose we have something like this:\n  //\n  // static <E> Set<E> singletonSet(E elem) {...}\n  //\n  // @AutoBuilder(callMethod = \"singletonSet\")\n  // interface SingletonSetBuilder<E> {\n  //   SingletonSetBuilder<E> setElem(E elem);\n  //   Set<E> build();\n  // }\n  //\n  // We want to check that the type of the setter `setElem` matches the type of the\n  // parameter it is setting. But in fact it doesn't: the type of the setter is\n  // E-of-SingletonSetBuilder while the type of the parameter is E-of-singletonSet. So we\n  // need to rewrite any type variables mentioned in parameters so that they use the corresponding\n  // types from the builder. We want to return a map where \"elem\" is mapped to\n  // E-of-SingletonSetBuilder, even though the `elem` that we get from the parameters of\n  // singletonSet is going to be E-of-singletonSet. And we also want that to work if the parameter\n  // is something more complicated, like List<? extends E>.\n  //\n  // For the corresponding situation with AutoValue, we have a way of dodging the problem somewhat.\n  // For an @AutoValue class Foo<E> with a builder Builder<E>, we can craft a DeclaredType\n  // Foo<E> where the E comes from Builder<E>, and we can use Types.asMemberOf to determine the\n  // return types of methods (which are what we want to rewrite in that case). But that doesn't\n  // work here because singletonSet is static and Types.asMemberOf would have no effect on it.\n  //\n  // So instead we take the type of each parameter and feed it through a TypeVisitor that rewrites\n  // type variables, rewriting from E-of-singletonSet to E-of-SingletonSetBuilder. Then we can use\n  // Types.isSameType or Types.isAssignable and it will work as we expect.\n  //\n  // In principle a similar situation arises with the return type Set<E> of singletonSet versus\n  // the return type Set<E> of SingletonSetBuilder.build(). But in fact we only use\n  // MoreTypes.equivalence to compare those, and that returns true for distinct type variables if\n  // they have the same name and bounds.\n  private static ImmutableMap<String, AnnotatedTypeMirror> rewriteParameterTypes(\n      Executable executable,\n      TypeElement builderType,\n      ErrorReporter errorReporter,\n      Types typeUtils) {\n    ImmutableList<TypeParameterElement> executableTypeParams = executable.typeParameters();\n    List<? extends TypeParameterElement> builderTypeParams = builderType.getTypeParameters();\n    if (!BuilderSpec.sameTypeParameters(executableTypeParams, builderTypeParams)) {\n      errorReporter.abortWithError(\n          builderType,\n          \"[AutoBuilderTypeParams] Builder type parameters %s must match type parameters %s of %s\",\n          TypeEncoder.typeParametersString(builderTypeParams),\n          TypeEncoder.typeParametersString(executableTypeParams),\n          executable);\n    }\n    if (executableTypeParams.isEmpty()) {\n      // Optimization for a common case. No point in doing all that type visiting if we have no\n      // variables to substitute.\n      return executable.parameters().stream()\n          .collect(\n              toImmutableMap(\n                  v -> v.getSimpleName().toString(), v -> new AnnotatedTypeMirror(v.asType())));\n    }\n    Map<Equivalence.Wrapper<TypeVariable>, TypeMirror> typeVariables = new LinkedHashMap<>();\n    for (int i = 0; i < executableTypeParams.size(); i++) {\n      TypeVariable from = MoreTypes.asTypeVariable(executableTypeParams.get(i).asType());\n      TypeVariable to = MoreTypes.asTypeVariable(builderTypeParams.get(i).asType());\n      typeVariables.put(MoreTypes.equivalence().wrap(from), to);\n    }\n    Function<TypeVariable, TypeMirror> substitute =\n        v -> typeVariables.get(MoreTypes.equivalence().wrap(v));\n    return executable.parameters().stream()\n        .collect(\n            toImmutableMap(\n                v -> v.getSimpleName().toString(),\n                v ->\n                    new AnnotatedTypeMirror(\n                        v.asType(),\n                        TypeVariables.substituteTypeVariables(v.asType(), substitute, typeUtils))));\n  }\n\n  @Override\n  Optional<String> propertyForBuilderGetter(ExecutableElement method) {\n    String methodName = method.getSimpleName().toString();\n    if (paramToPropertyName.containsValue(methodName)) {\n      return Optional.of(methodName);\n    }\n    if (AutoValueishProcessor.isPrefixedGetter(method)) {\n      int prefixLength = methodName.startsWith(\"get\") ? 3 : 2; // \"get\" or \"is\"\n      String unprefixed = methodName.substring(prefixLength);\n      String propertyName = PropertyNames.decapitalizeLikeJavaBeans(unprefixed);\n      if (paramToPropertyName.containsValue(propertyName)) {\n        return Optional.of(propertyName);\n      }\n      propertyName = PropertyNames.decapitalizeNormally(unprefixed);\n      if (paramToPropertyName.containsValue(propertyName)) {\n        return Optional.of(propertyName);\n      }\n    }\n    return Optional.empty();\n  }\n\n  @Override\n  void checkForFailedJavaBean(ExecutableElement rejectedSetter) {}\n\n  @Override\n  ImmutableBiMap<String, VariableElement> propertyElements() {\n    return paramToPropertyName.inverse();\n  }\n\n  @Override\n  TypeMirror originalPropertyType(VariableElement propertyElement) {\n    return propertyElement.asType();\n  }\n\n  @Override\n  String propertyString(VariableElement propertyElement) {\n    return \"parameter \\\"\" + propertyElement.getSimpleName() + \"\\\" of \" + executable;\n  }\n\n  @Override\n  String autoWhat() {\n    return \"AutoBuilder\";\n  }\n\n  @Override\n  String getterMustMatch() {\n    return \"a parameter of \" + executable;\n  }\n\n  @Override\n  String fooBuilderMustMatch() {\n    return \"foo\";\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/BuilderMethodClassifierForAutoValue.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.collect.Sets.difference;\n\nimport com.google.auto.common.MoreElements;\nimport com.google.common.collect.ImmutableBiMap;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Maps;\nimport java.util.Optional;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.TypeMirror;\n\nclass BuilderMethodClassifierForAutoValue extends BuilderMethodClassifier<ExecutableElement> {\n  private final ErrorReporter errorReporter;\n  private final ImmutableBiMap<ExecutableElement, String> getterToPropertyName;\n  private final ImmutableMap<String, ExecutableElement> getterNameToGetter;\n  private final TypeMirror builtType;\n\n  private BuilderMethodClassifierForAutoValue(\n      ErrorReporter errorReporter,\n      ProcessingEnvironment processingEnv,\n      TypeMirror builtType,\n      TypeElement builderType,\n      ImmutableBiMap<ExecutableElement, String> getterToPropertyName,\n      ImmutableMap<String, AnnotatedTypeMirror> rewrittenPropertyTypes,\n      Nullables nullables) {\n    super(\n        errorReporter,\n        processingEnv,\n        builtType,\n        builderType,\n        rewrittenPropertyTypes,\n        ImmutableSet.of(),\n        nullables);\n    this.errorReporter = errorReporter;\n    this.getterToPropertyName = getterToPropertyName;\n    this.getterNameToGetter =\n        Maps.uniqueIndex(getterToPropertyName.keySet(), m -> m.getSimpleName().toString());\n    this.builtType = builtType;\n  }\n\n  /**\n   * Classifies the given methods from a builder type and its ancestors.\n   *\n   * @param methods the abstract methods in {@code builderType} and its ancestors.\n   * @param errorReporter where to report errors.\n   * @param processingEnv the {@link ProcessingEnvironment} for annotation processing.\n   * @param autoValueClass the {@code AutoValue} class containing the builder.\n   * @param builderType the builder class or interface within {@code autoValueClass}.\n   * @param getterToPropertyName a map from getter methods to the properties they get.\n   * @param rewrittenPropertyTypes a map from property names to types. The types here use type\n   *     parameters from the builder class (if any) rather than from the {@code AutoValue} class,\n   *     even though the getter methods are in the latter.\n   * @param autoValueHasToBuilder true if the containing {@code @AutoValue} class has a {@code\n   *     toBuilder()} method.\n   * @return an {@code Optional} that contains the results of the classification if it was\n   *     successful or nothing if it was not.\n   */\n  static Optional<BuilderMethodClassifier<ExecutableElement>> classify(\n      Iterable<ExecutableElement> methods,\n      ErrorReporter errorReporter,\n      ProcessingEnvironment processingEnv,\n      TypeElement autoValueClass,\n      TypeElement builderType,\n      ImmutableBiMap<ExecutableElement, String> getterToPropertyName,\n      ImmutableMap<String, AnnotatedTypeMirror> rewrittenPropertyTypes,\n      Nullables nullables,\n      boolean autoValueHasToBuilder) {\n    BuilderMethodClassifier<ExecutableElement> classifier =\n        new BuilderMethodClassifierForAutoValue(\n            errorReporter,\n            processingEnv,\n            autoValueClass.asType(),\n            builderType,\n            getterToPropertyName,\n            rewrittenPropertyTypes,\n            nullables);\n    if (classifier.classifyMethods(methods, autoValueHasToBuilder)) {\n      return Optional.of(classifier);\n    } else {\n      return Optional.empty();\n    }\n  }\n\n  @Override\n  TypeMirror originalPropertyType(ExecutableElement propertyElement) {\n    return propertyElement.getReturnType();\n  }\n\n  @Override\n  String propertyString(ExecutableElement propertyElement) {\n    TypeElement type = MoreElements.asType(propertyElement.getEnclosingElement());\n    return \"property method \"\n        + type.getQualifiedName()\n        + \".\"\n        + propertyElement.getSimpleName()\n        + \"()\";\n  }\n\n  @Override\n  ImmutableBiMap<String, ExecutableElement> propertyElements() {\n    return getterToPropertyName.inverse();\n  }\n\n  @Override\n  Optional<String> propertyForBuilderGetter(ExecutableElement method) {\n    String methodName = method.getSimpleName().toString();\n    return Optional.ofNullable(getterNameToGetter.get(methodName)).map(getterToPropertyName::get);\n  }\n\n  @Override\n  void checkForFailedJavaBean(ExecutableElement rejectedSetter) {\n    ImmutableSet<ExecutableElement> allGetters = getterToPropertyName.keySet();\n    ImmutableSet<ExecutableElement> prefixedGetters =\n        AutoValueProcessor.prefixedGettersIn(allGetters);\n    if (prefixedGetters.size() < allGetters.size()\n        && prefixedGetters.size() >= allGetters.size() / 2) {\n      errorReporter.reportNote(\n          rejectedSetter,\n          \"This might be because you are using the getFoo() convention\"\n              + \" for some but not all methods. These methods don't follow the convention: %s\",\n          difference(allGetters, prefixedGetters));\n    }\n  }\n\n  @Override\n  String autoWhat() {\n    return \"AutoValue\";\n  }\n\n  @Override\n  String getterMustMatch() {\n    return \"a property method of \" + builtType;\n  }\n\n  @Override\n  String fooBuilderMustMatch() {\n    return \"foo() or getFoo()\";\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/BuilderRequiredProperties.java",
    "content": "/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static com.google.common.collect.ImmutableMap.toImmutableMap;\nimport static java.lang.Math.min;\nimport static java.math.RoundingMode.CEILING;\nimport static java.util.stream.Collectors.joining;\n\nimport com.google.auto.value.processor.AutoValueishProcessor.Property;\nimport com.google.common.annotations.VisibleForTesting;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.math.IntMath;\nimport java.util.stream.IntStream;\nimport java.util.stream.Stream;\n\n/**\n * Code generation to track which properties have been set in a builder.\n *\n * <p>Every property in an {@code @AutoValue} or {@code @AutoBuilder} builder must be set before the\n * {@code build()} method is called, with a few exceptions like {@code @Nullable} and {@code\n * Optional} properties. That means we must keep track of which ones have in fact been set. We do\n * that in two ways: for reference (non-primitive) types, we use {@code null} to indicate that the\n * value has not been set, while for primitive types we use a bitmask where each bit indicates\n * whether a certain primitive property has been set.\n *\n * <p>Additionally, for Kotlin constructors with default parameters, we track exactly which\n * properties have been set so we can invoke the constructor thas has a bitmask indicating the\n * properties to be defaulted.\n *\n * <p>The public methods in this class are accessed reflectively from the {@code builder.vm}\n * template. In that template, {@code $builderRequiredProperties} references an instance of this\n * class corresponding to the builder being generated. A reference like {@code\n * $builderRequiredProperties.markAsSet($p)} calls the method {@link #markAsSet} with the given\n * parameter. A reference like {@code $builderRequiredProperties.requiredProperties} is shorthand\n * for {@link #getRequiredProperties() $builderRequiredProperties.getProperties()}.\n */\npublic abstract class BuilderRequiredProperties {\n  static final BuilderRequiredProperties EMPTY = of(ImmutableSet.of(), ImmutableSet.of());\n\n  // Bitmasks are a bit fiddly because we use them in a couple of ways. The first way is where\n  // we are just using the bitmasks to track which primitive properties have been set. Then if\n  // we have three primitive properties we can just check that the bitmask is (1 << 3) - 1, the\n  // all-ones bitmask, to see that they have all been set. The second way is when we are also\n  // handling optional Kotlin parameters. Then the bitmasks are different: we have one bit for every\n  // property, primitive or not, optional or not. To check that the required primitive properties\n  // have been set, we need to check specific bits. For example if properties 1 and 3 are primitive\n  // then we need to check (~set$0 & ((1 << 1) | (1 << 3))) == 0. That tests that bits 1 and 3 are\n  // set, since if either of them is 0 then it will be 1 in ~set$0 and will survive the AND.  We can\n  // also isolate the bits representing optional Kotlin parameters similarly, and pass those to the\n  // special Kotlin constructor that handles default parameters. Kotlin uses bitmasks for that too:\n  // they have one bit per parameter, optional or not, but only the bits for optional parameters\n  // matter. We isolate those bits with `&` operations similar to what was described for primitive\n  // properties.  We also need the all-ones bitmask to implement a \"copy constructor\" builder, which\n  // starts out with all properties set.\n\n  /** All required properties. */\n  final ImmutableSet<Property> requiredProperties;\n\n  /**\n   * The bit index for each tracked property. Properties are tracked if they are primitive, or if\n   * this is a Kotlin constructor with default parameters. Non-tracked properties do not appear in\n   * this map.\n   */\n  final ImmutableMap<Property, Integer> trackedPropertyToIndex;\n\n  /**\n   * The integer fields that store the bitmask. In the usual case, where there are ≤32 tracked\n   * properties, we can pack the bitmask into one integer field. Its type is the smallest one that\n   * fits the required number of bits, for example {@code byte} if there are ≤8 tracked properties.\n   *\n   * <p>If there are {@literal >32} tracked properties, we will pack them into as few integer fields\n   * as possible. For example if there are 75 tracked properties (this can happen) then we will put\n   * numbers 0 to 31 in an {@code int}, 32 to 63 in a second {@code int}, and 64 to 75 in a {@code\n   * short}.\n   *\n   * <p>When there are {@literal >32} tracked properties, we could potentially pack them better if\n   * we used {@code long}. But sometimes AutoValue code gets translated into JavaScript, which\n   * doesn't handle long values natively. By the time you have that many properties you are probably\n   * not going to notice the difference between 5 ints or 2 longs plus an int.\n   */\n  final ImmutableList<BitmaskField> bitmaskFields;\n\n  /**\n   * Represents a field in which we will record which tracked properties from a certain set have\n   * been given a value.\n   */\n  private static class BitmaskField {\n    final Class<?> type;\n    final String name;\n\n    /**\n     * The source representation of the value this field has when all properties have been given a\n     * value.\n     */\n    final String allSetBitmask;\n\n    /**\n     * The source representation of the value this field has when all required properties have been\n     * given a value.\n     */\n    final String allRequiredBitmask;\n\n    BitmaskField(Class<?> type, String name, String allSetBitmask, String allRequiredBitmask) {\n      this.type = type;\n      this.name = name;\n      this.allSetBitmask = allSetBitmask;\n      this.allRequiredBitmask = allRequiredBitmask;\n    }\n  }\n\n  static BuilderRequiredProperties of(\n      ImmutableSet<Property> allProperties, ImmutableSet<Property> requiredProperties) {\n    boolean hasDefaults = allProperties.stream().anyMatch(Property::hasDefault);\n    return hasDefaults\n        ? new WithDefaults(allProperties, requiredProperties)\n        : new NoDefaults(requiredProperties);\n  }\n\n  private BuilderRequiredProperties(\n      ImmutableSet<Property> requiredProperties, ImmutableList<Property> trackedProperties) {\n    this.requiredProperties = requiredProperties;\n\n    int trackedCount = trackedProperties.size();\n    this.trackedPropertyToIndex =\n        IntStream.range(0, trackedCount)\n            .boxed()\n            .collect(toImmutableMap(trackedProperties::get, i -> i));\n\n    this.bitmaskFields =\n        IntStream.range(0, IntMath.divide(trackedCount, 32, CEILING))\n            .mapToObj(\n                i -> {\n                  int bitBase = i * 32;\n                  int remainingBits = trackedCount - bitBase;\n                  Class<?> type = classForBits(remainingBits);\n                  String name = \"set$\" + i;\n                  String allSetBitmask =\n                      (remainingBits >= 32) ? \"-1\" : hex((1 << remainingBits) - 1);\n                  String allRequiredBitmask =\n                      allRequiredBitmask(trackedProperties, bitBase, remainingBits);\n                  return new BitmaskField(type, name, allSetBitmask, allRequiredBitmask);\n                })\n            .collect(toImmutableList());\n  }\n\n  abstract String allRequiredBitmask(\n      ImmutableList<Property> trackedProperties, int bitBase, int remainingBits);\n\n  public ImmutableSet<Property> getRequiredProperties() {\n    return requiredProperties;\n  }\n\n  /**\n   * Returns code to declare any fields needed to track which properties have been set. Each line in\n   * the returned list should appear on a line of its own.\n   */\n  public ImmutableList<String> getFieldDeclarations() {\n    return bitmaskFields.stream()\n        .map(field -> \"private \" + field.type + \" \" + field.name + \";\")\n        .collect(toImmutableList());\n  }\n\n  /**\n   * Returns code to indicate that all tracked properties have received a value. This is needed in\n   * the {@code toBuilder()} constructor, since it assigns to the corresponding fields directly\n   * without going through their setters.\n   */\n  public ImmutableList<String> getInitToAllSet() {\n    return bitmaskFields.stream()\n        .map(field -> field.name + \" = \" + cast(field.type, field.allSetBitmask) + \";\")\n        .collect(toImmutableList());\n  }\n\n  /**\n   * Returns code to indicate that the given property has been set, if assigning to the property\n   * field is not enough. For reference (non-primitive) properties, assignment <i>is</i> enough, but\n   * for primitive properties we also need to set a bit in the bitmask.\n   */\n  public String markAsSet(Property p) {\n    Integer index = trackedPropertyToIndex.get(p);\n    if (index == null) {\n      return \"\";\n    }\n    BitmaskField field = bitmaskFields.get(index / 32);\n    // This use-case is why Java reduces int shift amounts mod 32. :-)\n    return field.name + \" |= \" + cast(field.type, hex(1 << index)) + \";\";\n  }\n\n  /**\n   * Returns an expression that is true if the given property is required but has not been set.\n   * Returns null if the property is not required.\n   */\n  public String missingRequiredProperty(Property p) {\n    return requiredProperties.contains(p) ? propertyNotSet(p) : null;\n  }\n\n  /**\n   * Returns an expression that is true if the given property has not been given a value. That's\n   * only different from {@link #missingRequiredProperty} if the property has a Kotlin default. If\n   * so, we don't require it to be set at build time (because Kotlin will supply the default), but\n   * we do require it to be set if it is accessed with a getter on the builder. We don't have access\n   * to Kotlin parameter defaults so we can't arrange for the builder field to have the same default\n   * value. Rather than returning a bogus zero value we say the value is unset.\n   */\n  public String noValueToGet(Property p) {\n    return (requiredProperties.contains(p) || p.hasDefault()) ? propertyNotSet(p) : null;\n  }\n\n  private String propertyNotSet(Property p) {\n    Integer index = trackedPropertyToIndex.get(p);\n    if (index == null) {\n      return \"this.\" + p + \" == null\";\n    }\n    BitmaskField field = bitmaskFields.get(index / 32);\n    return \"(\" + field.name + \" & \" + hex(1 << index) + \") == 0\";\n  }\n\n  /**\n   * Returns an expression that is true if any required properties have not been set. Should not be\n   * called if there are no required properties.\n   */\n  public abstract String getAnyMissing();\n\n  /**\n   * Returns additional constructor parameters to indicate what properties have been defaulted, or\n   * an empty string if there are none.\n   */\n  public abstract String getDefaultedBitmaskParameters();\n\n  /**\n   * The smallest primitive integer type that has at least this many bits, or {@code int} if the\n   * number of bits is more than 32.\n   */\n  private static Class<?> classForBits(int bits) {\n    return bits <= 8 ? byte.class : bits <= 16 ? short.class : int.class;\n  }\n\n  private static String cast(Class<?> type, String number) {\n    return (type == int.class) ? number : (\"(\" + type + \") \" + number);\n  }\n\n  @VisibleForTesting\n  static String hex(int number) {\n    if (number >= 0) {\n      if (number < 10) {\n        return Integer.toHexString(number);\n      }\n      if (number <= 0xffff) {\n        return \"0x\" + Integer.toHexString(number);\n      }\n    }\n    // It's harder to tell 0x7fffffff from 0x7ffffff than to tell 0x7fff_ffff from 0x7ff_ffff.\n    String lowNybble = Integer.toHexString(number & 0xffff);\n    String pad = \"000\".substring(lowNybble.length() - 1);\n    return \"0x\" + Integer.toHexString(number >>> 16) + \"_\" + pad + lowNybble;\n  }\n\n  /** Subclass for when there are no Kotlin default properties. */\n  private static final class NoDefaults extends BuilderRequiredProperties {\n    NoDefaults(ImmutableSet<Property> requiredProperties) {\n      super(requiredProperties, primitivePropertiesIn(requiredProperties));\n    }\n\n    private static ImmutableList<Property> primitivePropertiesIn(\n        ImmutableSet<Property> properties) {\n      return properties.stream().filter(p -> p.getKind().isPrimitive()).collect(toImmutableList());\n    }\n\n    @Override\n    String allRequiredBitmask(\n        ImmutableList<Property> trackedProperties, int bitBase, int remainingBits) {\n      // We have to be a bit careful with sign-extension. If we're using a byte and\n      // the mask is 0xff, then we'll write -1 instead. The comparison set$0 == 0xff\n      // would always fail since the byte value gets sign-extended to 0xffff_ffff.\n      // We should also write -1 if this is not the last field.\n      boolean minusOne = remainingBits >= 32 || remainingBits == 16 || remainingBits == 8;\n      return minusOne ? \"-1\" : hex((1 << remainingBits) - 1);\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * <p>We check the bitmask for primitive properties, and null checks for non-primitive ones.\n     */\n    @Override\n    public String getAnyMissing() {\n      Stream<String> primitiveConditions =\n          bitmaskFields.stream().map(field -> field.name + \" != \" + field.allRequiredBitmask);\n      Stream<String> nonPrimitiveConditions =\n          requiredProperties.stream()\n              .filter(p -> !trackedPropertyToIndex.containsKey(p))\n              .map(this::missingRequiredProperty);\n      return Stream.concat(primitiveConditions, nonPrimitiveConditions).collect(joining(\"\\n|| \"));\n    }\n\n    @Override\n    public String getDefaultedBitmaskParameters() {\n      return \"\";\n    }\n  }\n\n  /** Subclass for when there are Kotlin default properties. */\n  private static final class WithDefaults extends BuilderRequiredProperties {\n    private final ImmutableList<Property> allProperties;\n\n    WithDefaults(ImmutableSet<Property> allProperties, ImmutableSet<Property> requiredProperties) {\n      super(requiredProperties, allProperties.asList());\n      this.allProperties = allProperties.asList();\n    }\n\n    @Override\n    String allRequiredBitmask(\n        ImmutableList<Property> trackedProperties, int bitBase, int remainingBits) {\n      int requiredBits = 0;\n      for (int bit = 0; bit < remainingBits; bit++) {\n        Property p = trackedProperties.get(bitBase + bit);\n        if (requiredProperties.contains(p)) {\n          requiredBits |= 1 << bit;\n        }\n      }\n      return hex(requiredBits);\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * <p>Everything can be checked with bitmask operations. If bit <i>i</i> represents a required\n     * property then it must be 1 in the bitmask field. So if we invert it we must get 0, and if we\n     * do that for the field as a whole and AND with a bitmask selecting only required properties we\n     * should get 0.\n     */\n    @Override\n    public String getAnyMissing() {\n      return bitmaskFields.stream()\n          .filter(field -> !field.allRequiredBitmask.equals(\"0\"))\n          .map(field -> \"(~\" + field.name + \" & \" + field.allRequiredBitmask + \") != 0\")\n          .collect(joining(\"\\n|| \"));\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * <p>When there are default parameters, we're calling the special constructor that has one or\n     * more bitmask parameters at the end. Bit <i>i</i> is set if parameter <i>i</i> (zero-origin)\n     * has its default value, and then the actual value passed for that parameter is ignored. Our\n     * bitmask field has a 1 for any parameter that has been set, meaning it has a 0 for any\n     * parameter that has been defaulted. So we need to invert it, and we also want to AND it with a\n     * bitmask that selects just the bits for parameters with defaults. (The AND probably isn't\n     * strictly necessary, since the constructor code doesn't actually look at those other bits, but\n     * it seems cleaner.) If the bitmask for parameters with defaults is 0 then we can just use 0\n     * for that bitmask, and if it is ~0 (all 1 bits) then we can skip the AND.\n     *\n     * <p>That special constructor has an additional dummy parameter of type {@code\n     * DefaultConstructorMarker}. We just pass {@code null} to that parameter.\n     */\n    @Override\n    public String getDefaultedBitmaskParameters() {\n      ImmutableList.Builder<Integer> defaultedBitmasksBuilder = ImmutableList.builder();\n      for (int bitBase = 0; bitBase < allProperties.size(); bitBase += 32) {\n        int bitCount = min(32, allProperties.size() - bitBase);\n        int defaultedBitmask = 0;\n        for (int i = 0; i < bitCount; i++) {\n          if (allProperties.get(bitBase + i).hasDefault()) {\n            defaultedBitmask |= 1 << i;\n          }\n        }\n        defaultedBitmasksBuilder.add(defaultedBitmask);\n      }\n      ImmutableList<Integer> defaultedBitmasks = defaultedBitmasksBuilder.build();\n      return IntStream.range(0, bitmaskFields.size())\n          .mapToObj(\n              i -> {\n                int defaultedBitmask = defaultedBitmasks.get(i);\n                switch (defaultedBitmask) {\n                  case 0:\n                    return \"0\";\n                  case ~0:\n                    return \"~\" + bitmaskFields.get(i).name;\n                  default:\n                    return \"~\" + bitmaskFields.get(i).name + \" & \" + hex(defaultedBitmask);\n                }\n              })\n          .collect(joining(\",\\n\", \",\\n\", \",\\nnull\"));\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/BuilderSpec.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.auto.common.MoreElements.getLocalAndInheritedMethods;\nimport static com.google.auto.value.processor.AutoValueishProcessor.hasAnnotationMirror;\nimport static com.google.auto.value.processor.AutoValueishProcessor.hasVisibleNoArgConstructor;\nimport static com.google.auto.value.processor.AutoValueishProcessor.nullableAnnotationFor;\nimport static com.google.auto.value.processor.ClassNames.AUTO_VALUE_BUILDER_NAME;\nimport static com.google.common.collect.ImmutableSet.toImmutableSet;\nimport static com.google.common.collect.Sets.immutableEnumSet;\nimport static java.util.stream.Collectors.toList;\nimport static java.util.stream.Collectors.toSet;\nimport static javax.lang.model.util.ElementFilter.methodsIn;\nimport static javax.lang.model.util.ElementFilter.typesIn;\n\nimport com.google.auto.common.MoreElements;\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.value.extension.AutoValueExtension;\nimport com.google.auto.value.processor.AutoValueishProcessor.Property;\nimport com.google.auto.value.processor.PropertyBuilderClassifier.PropertyBuilder;\nimport com.google.common.collect.ImmutableBiMap;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Iterables;\nimport com.google.common.collect.Maps;\nimport com.google.common.collect.Sets;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.Set;\nimport java.util.function.Function;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ElementKind;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.Modifier;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.TypeParameterElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.ExecutableType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.Types;\n\n/**\n * Support for AutoValue builders.\n *\n * @author Éamonn McManus\n */\nclass BuilderSpec {\n  private final TypeElement autoValueClass;\n  private final ProcessingEnvironment processingEnv;\n  private final ErrorReporter errorReporter;\n\n  BuilderSpec(\n      TypeElement autoValueClass,\n      ProcessingEnvironment processingEnv,\n      ErrorReporter errorReporter) {\n    this.autoValueClass = autoValueClass;\n    this.processingEnv = processingEnv;\n    this.errorReporter = errorReporter;\n  }\n\n  private static final ImmutableSet<ElementKind> CLASS_OR_INTERFACE =\n      immutableEnumSet(ElementKind.CLASS, ElementKind.INTERFACE);\n\n  /**\n   * Determines if the {@code @AutoValue} class for this instance has a correct nested\n   * {@code @AutoValue.Builder} class or interface and return a representation of it in an {@code\n   * Optional} if so.\n   */\n  Optional<Builder> getBuilder() {\n    Optional<TypeElement> builderTypeElement = Optional.empty();\n    for (TypeElement containedClass : typesIn(autoValueClass.getEnclosedElements())) {\n      if (hasAnnotationMirror(containedClass, AUTO_VALUE_BUILDER_NAME)) {\n        findBuilderError(containedClass)\n            .ifPresent(error -> errorReporter.reportError(containedClass, \"%s\", error));\n        if (builderTypeElement.isPresent()) {\n          errorReporter.reportError(\n              containedClass,\n              \"[AutoValueTwoBuilders] %s already has a Builder: %s\",\n              autoValueClass,\n              builderTypeElement.get());\n        } else {\n          builderTypeElement = Optional.of(containedClass);\n        }\n      }\n    }\n\n    if (builderTypeElement.isPresent()) {\n      return builderFrom(builderTypeElement.get());\n    } else {\n      return Optional.empty();\n    }\n  }\n\n  /** Finds why this {@code @AutoValue.Builder} class is bad, if it is bad. */\n  private Optional<String> findBuilderError(TypeElement builderTypeElement) {\n    if (!CLASS_OR_INTERFACE.contains(builderTypeElement.getKind())) {\n      return Optional.of(\n          \"[AutoValueBuilderClass] @AutoValue.Builder can only apply to a class or an\"\n              + \" interface\");\n    } else if (!builderTypeElement.getModifiers().contains(Modifier.STATIC)) {\n      return Optional.of(\n          \"[AutoValueInnerBuilder] @AutoValue.Builder cannot be applied to a non-static class\");\n    } else if (builderTypeElement.getKind().equals(ElementKind.CLASS)\n        && !hasVisibleNoArgConstructor(builderTypeElement)) {\n      return Optional.of(\n          \"[AutoValueBuilderConstructor] @AutoValue.Builder class must have a non-private no-arg\"\n              + \" constructor\");\n    }\n    return Optional.empty();\n  }\n\n  /** Representation of an {@code AutoValue.Builder} class or interface. */\n  class Builder implements AutoValueExtension.BuilderContext {\n    private final TypeElement builderTypeElement;\n    private ImmutableSet<ExecutableElement> toBuilderMethods;\n    private ImmutableSet<ExecutableElement> builderAbstractMethods;\n    private ExecutableElement buildMethod;\n    private BuilderMethodClassifier<?> classifier;\n\n    Builder(TypeElement builderTypeElement) {\n      this.builderTypeElement = builderTypeElement;\n    }\n\n    @Override\n    public TypeElement builderType() {\n      return builderTypeElement;\n    }\n\n    @Override\n    public Set<ExecutableElement> builderMethods() {\n      return methodsIn(autoValueClass.getEnclosedElements()).stream()\n          .filter(\n              m ->\n                  m.getParameters().isEmpty()\n                      && m.getModifiers().contains(Modifier.STATIC)\n                      && !m.getModifiers().contains(Modifier.PRIVATE)\n                      && erasedTypeIs(m.getReturnType(), builderTypeElement))\n          .collect(toSet());\n    }\n\n    @Override\n    public Optional<ExecutableElement> buildMethod() {\n      Types typeUtils = processingEnv.getTypeUtils();\n      DeclaredType builderTypeMirror = MoreTypes.asDeclared(builderTypeElement.asType());\n      return MoreElements.getLocalAndInheritedMethods(\n              builderTypeElement, typeUtils, processingEnv.getElementUtils())\n          .stream()\n          .filter(\n              m ->\n                  m.getSimpleName().contentEquals(\"build\")\n                      && !m.getModifiers().contains(Modifier.PRIVATE)\n                      && !m.getModifiers().contains(Modifier.STATIC)\n                      && m.getParameters().isEmpty())\n          .filter(\n              m -> {\n                ExecutableType methodMirror =\n                    MoreTypes.asExecutable(typeUtils.asMemberOf(builderTypeMirror, m));\n                return erasedTypeIs(methodMirror.getReturnType(), autoValueClass);\n              })\n          .findFirst();\n    }\n\n    @Override\n    public ExecutableElement autoBuildMethod() {\n      return buildMethod;\n    }\n\n    @Override\n    public Map<String, Set<ExecutableElement>> setters() {\n      return Maps.transformValues(\n          classifier.propertyNameToSetters().asMap(),\n          propertySetters ->\n              propertySetters.stream().map(PropertySetter::getSetter).collect(toSet()));\n    }\n\n    @Override\n    public Map<String, ExecutableElement> propertyBuilders() {\n      return Maps.transformValues(\n          classifier.propertyNameToPropertyBuilder(), PropertyBuilder::getPropertyBuilderMethod);\n    }\n\n    private boolean erasedTypeIs(TypeMirror type, TypeElement baseType) {\n      return type.getKind().equals(TypeKind.DECLARED)\n          && MoreTypes.asDeclared(type).asElement().equals(baseType);\n    }\n\n    @Override\n    public Set<ExecutableElement> toBuilderMethods() {\n      return toBuilderMethods;\n    }\n\n    ImmutableSet<ExecutableElement> builderAbstractMethods() {\n      if (builderAbstractMethods == null) {\n        builderAbstractMethods = abstractMethods(builderTypeElement, processingEnv);\n      }\n      return builderAbstractMethods;\n    }\n\n    /**\n     * Finds any methods in the set that return the builder type. If the builder has type parameters\n     * {@code <A, B>}, then the return type of the method must be {@code Builder<A, B>} with the\n     * same parameter names. We enforce elsewhere that the names and bounds of the builder\n     * parameters must be the same as those of the {@code @AutoValue} class. Here's a correct\n     * example:\n     *\n     * <pre>{@code\n     * @AutoValue abstract class Foo<A extends Number, B> {\n     *   abstract int someProperty();\n     *\n     *   abstract Builder<A, B> toBuilder();\n     *\n     *   interface Builder<A extends Number, B> {...}\n     * }\n     * }</pre>\n     *\n     * <p>We currently impose that there cannot be more than one such method.\n     */\n    ImmutableSet<ExecutableElement> toBuilderMethods(\n        Types typeUtils, TypeElement autoValueType, Set<ExecutableElement> abstractMethods) {\n\n      List<String> builderTypeParamNames =\n          builderTypeElement.getTypeParameters().stream()\n              .map(e -> e.getSimpleName().toString())\n              .collect(toList());\n\n      DeclaredType autoValueTypeMirror = MoreTypes.asDeclared(autoValueType.asType());\n      ImmutableSet.Builder<ExecutableElement> methods = ImmutableSet.builder();\n      for (ExecutableElement method : abstractMethods) {\n        if (!method.getParameters().isEmpty()) {\n          continue;\n        }\n        ExecutableType methodMirror =\n            MoreTypes.asExecutable(typeUtils.asMemberOf(autoValueTypeMirror, method));\n        TypeMirror returnTypeMirror = methodMirror.getReturnType();\n        if (builderTypeElement.equals(typeUtils.asElement(returnTypeMirror))) {\n          methods.add(method);\n          DeclaredType returnType = MoreTypes.asDeclared(returnTypeMirror);\n          List<String> typeArguments =\n              returnType.getTypeArguments().stream()\n                  .filter(t -> t.getKind().equals(TypeKind.TYPEVAR))\n                  .map(t -> typeUtils.asElement(t).getSimpleName().toString())\n                  .collect(toList());\n          if (!builderTypeParamNames.equals(typeArguments)) {\n            errorReporter.reportError(\n                method,\n                \"[AutoValueBuilderConverterReturn] Builder converter method should return %s%s\",\n                builderTypeElement,\n                TypeSimplifier.actualTypeParametersString(builderTypeElement));\n          }\n        }\n      }\n      ImmutableSet<ExecutableElement> builderMethods = methods.build();\n      if (builderMethods.size() > 1) {\n        errorReporter.reportError(\n            builderMethods.iterator().next(),\n            \"[AutoValueTwoBuilderConverters] There can be at most one builder converter method\");\n      }\n      this.toBuilderMethods = builderMethods;\n      return builderMethods;\n    }\n\n    void defineVarsForAutoValue(\n        AutoValueOrBuilderTemplateVars vars,\n        ImmutableBiMap<ExecutableElement, String> getterToPropertyName,\n        Nullables nullables,\n        ImmutableSet<ExecutableElement> consumedBuilderAbstractMethods) {\n      Iterable<ExecutableElement> builderMethods =\n          Sets.difference(builderAbstractMethods, consumedBuilderAbstractMethods);\n      boolean autoValueHasToBuilder = toBuilderMethods != null && !toBuilderMethods.isEmpty();\n      ImmutableMap<ExecutableElement, AnnotatedTypeMirror> getterToPropertyType =\n          TypeVariables.rewriteReturnTypes(\n              processingEnv.getTypeUtils(),\n              getterToPropertyName.keySet(),\n              autoValueClass,\n              builderTypeElement);\n      ImmutableMap.Builder<String, AnnotatedTypeMirror> rewrittenPropertyTypes =\n          ImmutableMap.builder();\n      getterToPropertyType.forEach(\n          (getter, type) -> rewrittenPropertyTypes.put(getterToPropertyName.get(getter), type));\n      Optional<BuilderMethodClassifier<ExecutableElement>> optionalClassifier =\n          BuilderMethodClassifierForAutoValue.classify(\n              builderMethods,\n              errorReporter,\n              processingEnv,\n              autoValueClass,\n              builderTypeElement,\n              getterToPropertyName,\n              rewrittenPropertyTypes.build(),\n              nullables,\n              autoValueHasToBuilder);\n      if (!optionalClassifier.isPresent()) {\n        return;\n      }\n      for (ExecutableElement method : methodsIn(builderTypeElement.getEnclosedElements())) {\n        if (method.getSimpleName().contentEquals(\"builder\")\n            && method.getModifiers().contains(Modifier.STATIC)\n            && method.getAnnotationMirrors().isEmpty()\n            && !(vars instanceof AutoBuilderTemplateVars)) {\n          // For now we don't warn for methods with annotations, because for example we do want to\n          // allow Jackson's @JsonCreator. We also don't warn if this is an @AutoBuilder.\n          errorReporter.reportWarning(\n              method,\n              \"[AutoValueBuilderInBuilder] Static builder() method should be in the containing\"\n                  + \" class\");\n        }\n      }\n      defineVars(vars, optionalClassifier.get());\n    }\n\n    void defineVars(AutoValueOrBuilderTemplateVars vars, BuilderMethodClassifier<?> classifier) {\n      this.classifier = classifier;\n      Set<ExecutableElement> buildMethods = classifier.buildMethods();\n      if (buildMethods.size() != 1) {\n        Set<? extends Element> errorElements =\n            buildMethods.isEmpty() ? ImmutableSet.of(builderTypeElement) : buildMethods;\n        for (Element buildMethod : errorElements) {\n          errorReporter.reportError(\n              buildMethod,\n              \"[AutoValueBuilderBuild] Builder must have a single no-argument method, typically\"\n                  + \" called build(), that returns %s%s\",\n              autoValueClass,\n              typeParamsString());\n        }\n        errorReporter.abortIfAnyError();\n        return;\n      }\n      this.buildMethod = Iterables.getOnlyElement(buildMethods);\n      vars.builderIsInterface = builderTypeElement.getKind() == ElementKind.INTERFACE;\n      vars.builderTypeName = TypeSimplifier.classNameOf(builderTypeElement);\n      vars.builderFormalTypes =\n          TypeEncoder.typeParametersString(builderTypeElement.getTypeParameters());\n      vars.builderActualTypes = TypeSimplifier.actualTypeParametersString(builderTypeElement);\n      vars.buildMethod = Optional.of(new SimpleMethod(buildMethod));\n      vars.builderGetters = classifier.builderGetters();\n      vars.builderSetters = classifier.propertyNameToSetters();\n\n      vars.builderPropertyBuilders =\n          ImmutableMap.copyOf(classifier.propertyNameToPropertyBuilder());\n\n      ImmutableSet<Property> requiredProperties =\n          vars.props.stream()\n              .filter(p -> !p.isNullable())\n              .filter(p -> p.getBuilderInitializer().isEmpty())\n              .filter(p -> !p.hasDefault())\n              .filter(p -> !vars.builderPropertyBuilders.containsKey(p.getName()))\n              .collect(toImmutableSet());\n      vars.builderRequiredProperties = BuilderRequiredProperties.of(vars.props, requiredProperties);\n    }\n  }\n\n  /**\n   * Information about a builder property getter, referenced from the autovalue.vm template. A\n   * property called foo (defined by a method {@code T foo()} or {@code T getFoo()}) can have a\n   * getter method in the builder with the same name ({@code foo()} or {@code getFoo()}) and a\n   * return type of either {@code T} or {@code Optional<T>}. The {@code Optional<T>} form can be\n   * used to tell whether the property has been set. Here, {@code Optional<T>} can be either {@code\n   * java.util.Optional} or {@code com.google.common.base.Optional}. If {@code T} is {@code int},\n   * {@code long}, or {@code double}, then instead of {@code Optional<T>} we can have {@code\n   * OptionalInt} etc. If {@code T} is a primitive type (including these ones but also the other\n   * five) then {@code Optional<T>} can be the corresponding boxed type.\n   */\n  public static class PropertyGetter {\n    private final String name;\n    private final String access;\n    private final String type;\n    private final Optionalish optional;\n\n    /**\n     * Makes a new {@code PropertyGetter} instance.\n     *\n     * @param method the source method which this getter is implementing.\n     * @param type the type that the getter returns. This is written to take imports into account,\n     *     so it might be {@code List<String>} for example. It is either identical to the type of\n     *     the corresponding getter in the {@code @AutoValue} class, or it is an optional wrapper,\n     *     like {@code Optional<List<String>>}.\n     * @param optional a representation of the {@code Optional} type that the getter returns, if\n     *     this is an optional getter, or null otherwise. An optional getter is one that returns\n     *     {@code Optional<T>} rather than {@code T}, as explained above.\n     */\n    PropertyGetter(ExecutableElement method, String type, Optionalish optional) {\n      this.name = method.getSimpleName().toString();\n      this.access = SimpleMethod.access(method);\n      this.type = type;\n      this.optional = optional;\n    }\n\n    public String getName() {\n      return name;\n    }\n\n    public String getAccess() {\n      return access;\n    }\n\n    public String getType() {\n      return type;\n    }\n\n    public Optionalish getOptional() {\n      return optional;\n    }\n  }\n\n  /**\n   * Specifies how to copy a parameter value into the target type. This might be the identity, or it\n   * might be something like {@code ImmutableList.of(...)} or {@code Optional.ofNullable(...)}.\n   */\n  static class Copier {\n    static final Copier IDENTITY = acceptingNull(x -> x);\n\n    private final Function<String, String> copy;\n    private final boolean acceptsNull;\n\n    private Copier(Function<String, String> copy, boolean acceptsNull) {\n      this.copy = copy;\n      this.acceptsNull = acceptsNull;\n    }\n\n    static Copier acceptingNull(Function<String, String> copy) {\n      return new Copier(copy, true);\n    }\n\n    static Copier notAcceptingNull(Function<String, String> copy) {\n      return new Copier(copy, false);\n    }\n  }\n\n  /**\n   * Information about a property setter, referenced from the autovalue.vm template. A property\n   * called foo (defined by a method {@code T foo()} or {@code T getFoo()}) can have a setter method\n   * {@code foo(T)} or {@code setFoo(T)} that returns the builder type. Additionally, it can have a\n   * setter with a type that can be copied to {@code T} through a {@code copyOf} method; for example\n   * a property {@code foo} of type {@code ImmutableSet<String>} can be set with a method {@code\n   * setFoo(Collection<String> foos)}. And, if {@code T} is {@code Optional}, it can have a setter\n   * with a type that can be copied to {@code T} through {@code Optional.of}.\n   */\n  public static class PropertySetter {\n    private final ExecutableElement setter;\n    private final String access;\n    private final String name;\n    private final String parameterTypeString;\n    private final boolean primitiveParameter;\n    private final String nullableAnnotation;\n    private final Copier copier;\n\n    PropertySetter(ExecutableElement setter, AnnotatedTypeMirror parameterType, Copier copier) {\n      this.setter = setter;\n      this.copier = copier;\n      this.access = SimpleMethod.access(setter);\n      this.name = setter.getSimpleName().toString();\n      primitiveParameter = parameterType.getKind().isPrimitive();\n      this.parameterTypeString = parameterTypeString(setter, parameterType);\n      VariableElement parameterElement = Iterables.getOnlyElement(setter.getParameters());\n      Optional<String> maybeNullable =\n          nullableAnnotationFor(parameterElement, parameterType.getType());\n      this.nullableAnnotation = maybeNullable.orElse(\"\");\n    }\n\n    ExecutableElement getSetter() {\n      return setter;\n    }\n\n    private static String parameterTypeString(\n        ExecutableElement setter, AnnotatedTypeMirror parameterType) {\n      if (setter.isVarArgs()) {\n        TypeMirror componentType = MoreTypes.asArray(parameterType.getType()).getComponentType();\n        // This is a bit ugly. It's OK to annotate just the component type, because if it is\n        // say `@Nullable String` then we will end up with `@Nullable String...`. Unlike the\n        // normal array case, we can't have the situation where the array itself is annotated;\n        // you can write `String @Nullable []` to mean that, but you can't write\n        // `String @Nullable ...`.\n        return TypeEncoder.encodeWithAnnotations(componentType) + \"...\";\n      } else {\n        return TypeEncoder.encodeWithAnnotations(parameterType);\n      }\n    }\n\n    public String getAccess() {\n      return access;\n    }\n\n    public String getName() {\n      return name;\n    }\n\n    public String getParameterType() {\n      return parameterTypeString;\n    }\n\n    public boolean getPrimitiveParameter() {\n      return primitiveParameter;\n    }\n\n    public String getNullableAnnotation() {\n      return nullableAnnotation;\n    }\n\n    public String copy(Property property) {\n      String copy = copier.copy.apply(property.toString());\n      if (property.isNullable() && !copier.acceptsNull) {\n        copy = String.format(\"(%s == null ? null : %s)\", property, copy);\n      }\n      return copy;\n    }\n  }\n\n  /**\n   * Returns a representation of the given {@code @AutoValue.Builder} class or interface. If the\n   * class or interface has abstract methods that could not be part of any builder, emits error\n   * messages and returns Optional.empty().\n   */\n  private Optional<Builder> builderFrom(TypeElement builderTypeElement) {\n\n    // We require the builder to have the same type parameters as the @AutoValue class, meaning the\n    // same names and bounds. In principle the type parameters could have different names, but that\n    // would be confusing, and our code would reject it anyway because it wouldn't consider that\n    // the return type of Foo<U> build() was really the same as the declaration of Foo<T>. This\n    // check produces a better error message in that case and similar ones.\n\n    if (!sameTypeParameters(autoValueClass, builderTypeElement)) {\n      errorReporter.reportError(\n          builderTypeElement,\n          \"[AutoValueTypeParamMismatch] Type parameters of %s must have same names and bounds as\"\n              + \" type parameters of %s\",\n          builderTypeElement,\n          autoValueClass);\n      return Optional.empty();\n    }\n    return Optional.of(new Builder(builderTypeElement));\n  }\n\n  private static boolean sameTypeParameters(TypeElement a, TypeElement b) {\n    return sameTypeParameters(a.getTypeParameters(), b.getTypeParameters());\n  }\n\n  static boolean sameTypeParameters(\n      List<? extends TypeParameterElement> aParams, List<? extends TypeParameterElement> bParams) {\n    int nTypeParameters = aParams.size();\n    if (nTypeParameters != bParams.size()) {\n      return false;\n    }\n    for (int i = 0; i < nTypeParameters; i++) {\n      TypeParameterElement aParam = aParams.get(i);\n      TypeParameterElement bParam = bParams.get(i);\n      if (!aParam.getSimpleName().equals(bParam.getSimpleName())) {\n        return false;\n      }\n      Set<TypeMirror> aBounds = new TypeMirrorSet(aParam.getBounds());\n      Set<TypeMirror> bBounds = new TypeMirrorSet(bParam.getBounds());\n      if (!aBounds.equals(bBounds)) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  /**\n   * Returns a set of all abstract methods in the given TypeElement or inherited from ancestors. If\n   * any of the abstract methods has a return type or parameter type that is not currently defined\n   * then this method will throw an exception that will cause us to defer processing of the current\n   * class until a later annotation-processing round.\n   */\n  static ImmutableSet<ExecutableElement> abstractMethods(\n      TypeElement typeElement, ProcessingEnvironment processingEnv) {\n    Set<ExecutableElement> methods =\n        getLocalAndInheritedMethods(\n            typeElement, processingEnv.getTypeUtils(), processingEnv.getElementUtils());\n    ImmutableSet.Builder<ExecutableElement> abstractMethods = ImmutableSet.builder();\n    for (ExecutableElement method : methods) {\n      if (method.getModifiers().contains(Modifier.ABSTRACT)) {\n        MissingTypes.deferIfMissingTypesIn(method);\n        abstractMethods.add(method);\n      }\n    }\n    return abstractMethods.build();\n  }\n\n  private String typeParamsString() {\n    return TypeSimplifier.actualTypeParametersString(autoValueClass);\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/ClassNames.java",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\n/**\n * Names of classes that are referenced in the processors.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\nfinal class ClassNames {\n  private ClassNames() {}\n\n  static final String AUTO_VALUE_PACKAGE_NAME = \"com.google.auto.value.\";\n  static final String AUTO_ANNOTATION_NAME = AUTO_VALUE_PACKAGE_NAME + \"AutoAnnotation\";\n  static final String AUTO_ONE_OF_NAME = AUTO_VALUE_PACKAGE_NAME + \"AutoOneOf\";\n  static final String AUTO_VALUE_NAME = AUTO_VALUE_PACKAGE_NAME + \"AutoValue\";\n  static final String AUTO_VALUE_BUILDER_NAME = AUTO_VALUE_NAME + \".Builder\";\n  static final String AUTO_BUILDER_NAME = AUTO_VALUE_PACKAGE_NAME + \"AutoBuilder\";\n  static final String COPY_ANNOTATIONS_NAME = AUTO_VALUE_NAME + \".CopyAnnotations\";\n  static final String KOTLIN_METADATA_NAME = \"kot\".concat(\"lin.Metadata\"); // defeat shading\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/EclipseHack.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.collect.ImmutableList.toImmutableList;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.common.collect.ImmutableList;\nimport java.util.List;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.Name;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\n\n/**\n * Hacks needed to work around various bugs and incompatibilities in Eclipse's implementation of\n * annotation processing.\n *\n * @author Éamonn McManus\n */\nclass EclipseHack {\n  private EclipseHack() {}\n\n  /**\n   * Returns the enclosing type of {@code type}, if {@code type} is an inner class. Otherwise\n   * returns a {@code NoType}. This is what {@link DeclaredType#getEnclosingType()} is supposed to\n   * do. However, some versions of Eclipse have a bug where, for example, asking for the enclosing\n   * type of {@code PrimitiveIterator.OfInt} will return {@code PrimitiveIterator<T, T_CONS>} rather\n   * than plain {@code PrimitiveIterator}, as if {@code OfInt} were an inner class rather than a\n   * static one. This would lead us to write a reference to {@code OfInt} as {@code\n   * PrimitiveIterator<T, T_CONS>.OfInt}, which would obviously break. We attempt to avert this by\n   * detecting that:\n   *\n   * <ul>\n   *   <li>there is an enclosing type that is a {@code DeclaredType}, which should mean that {@code\n   *       type} is an inner class;\n   *   <li>we are in the Eclipse compiler;\n   *   <li>the type arguments of the purported enclosing type are all type variables with the same\n   *       names as the corresponding type parameters.\n   * </ul>\n   *\n   * <p>If all these conditions are met, we assume we're hitting the Eclipse bug, and we return no\n   * enclosing type instead. That does mean that in the unlikely event where we really do have an\n   * inner class of an instantiation of the outer class with type arguments that happen to be type\n   * variables with the same names as the corresponding parameters, we will do the wrong thing on\n   * Eclipse. But doing the wrong thing in that case is better than doing the wrong thing in the\n   * usual case.\n   */\n  static TypeMirror getEnclosingType(DeclaredType type) {\n    TypeMirror enclosing = type.getEnclosingType();\n    if (!enclosing.getKind().equals(TypeKind.DECLARED)\n        || !enclosing.getClass().getName().contains(\"eclipse\")) {\n      // If the class representing the enclosing type comes from the Eclipse compiler, it will be\n      // something like org.eclipse.jdt.internal.compiler.apt.model.DeclaredTypeImpl. If we're not\n      // in the Eclipse compiler then we don't expect to see \"eclipse\" in the name of this\n      // implementation class.\n      return enclosing;\n    }\n    DeclaredType declared = MoreTypes.asDeclared(enclosing);\n    List<? extends TypeMirror> arguments = declared.getTypeArguments();\n    if (!arguments.isEmpty()) {\n      boolean allVariables = arguments.stream().allMatch(t -> t.getKind().equals(TypeKind.TYPEVAR));\n      if (allVariables) {\n        ImmutableList<Name> argumentNames =\n            arguments.stream()\n                .map(t -> MoreTypes.asTypeVariable(t).asElement().getSimpleName())\n                .collect(toImmutableList());\n        TypeElement enclosingElement = MoreTypes.asTypeElement(declared);\n        ImmutableList<Name> parameterNames =\n            enclosingElement.getTypeParameters().stream()\n                .map(Element::getSimpleName)\n                .collect(toImmutableList());\n        if (argumentNames.equals(parameterNames)) {\n          // We're going to return a NoType. We don't have a Types to hand so we can't call\n          // Types.getNoType(). Instead, just keep going through outer types until we get to\n          // the outside, which will be a NoType.\n          while (enclosing.getKind().equals(TypeKind.DECLARED)) {\n            enclosing = MoreTypes.asDeclared(enclosing).getEnclosingType();\n          }\n          return enclosing;\n        }\n      }\n    }\n    return declared;\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/ErrorReporter.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport com.google.errorprone.annotations.FormatMethod;\nimport javax.annotation.processing.Messager;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.element.Element;\nimport javax.tools.Diagnostic;\n\n/**\n * Handle error reporting for an annotation processor.\n *\n * @author Éamonn McManus\n */\nclass ErrorReporter {\n  private final Messager messager;\n  private int errorCount;\n\n  ErrorReporter(ProcessingEnvironment processingEnv) {\n    this.messager = processingEnv.getMessager();\n  }\n\n  /**\n   * Issue a compilation note.\n   *\n   * @param e the element to which it pertains\n   * @param format the format string for the text of the note\n   * @param args arguments for the format string\n   */\n  @FormatMethod\n  void reportNote(Element e, String format, Object... args) {\n    messager.printMessage(Diagnostic.Kind.NOTE, String.format(format, args), e);\n  }\n\n  /**\n   * Issue a compilation warning.\n   *\n   * @param e the element to which it pertains\n   * @param format the format string for the text of the warning\n   * @param args arguments for the format string\n   */\n  @FormatMethod\n  void reportWarning(Element e, String format, Object... args) {\n    messager.printMessage(Diagnostic.Kind.WARNING, String.format(format, args), e);\n  }\n\n  /**\n   * Issue a compilation error. This method does not throw an exception, since we want to continue\n   * processing and perhaps report other errors. It is a good idea to introduce a test case in\n   * CompilationTest for any new call to reportError(...) to ensure that we continue correctly after\n   * an error.\n   *\n   * @param e the element to which it pertains\n   * @param format the format string for the text of the warning\n   * @param args arguments for the format string\n   */\n  @FormatMethod\n  void reportError(Element e, String format, Object... args) {\n    messager.printMessage(Diagnostic.Kind.ERROR, String.format(format, args), e);\n    errorCount++;\n  }\n\n  /**\n   * Issue a compilation error and abandon the processing of this class. This does not prevent the\n   * processing of other classes.\n   *\n   * @param e the element to which it pertains\n   * @param format the format string for the text of the error\n   * @param args arguments for the format string\n   * @return This method does not return, but is declared with an exception return type so you can\n   *     write {@code throw abortWithError(...)} to tell the compiler that.\n   * @throws AbortProcessingException always\n   */\n  @FormatMethod\n  AbortProcessingException abortWithError(Element e, String format, Object... args) {\n    reportError(e, format, args);\n    throw new AbortProcessingException();\n  }\n\n  /** The number of errors that have been output by calls to {@link #reportError}. */\n  int errorCount() {\n    return errorCount;\n  }\n\n  /** Abandon the processing of this class if any errors have been output. */\n  void abortIfAnyError() {\n    if (errorCount > 0) {\n      throw new AbortProcessingException();\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/Executable.java",
    "content": "/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static java.util.stream.Collectors.joining;\n\nimport com.google.auto.common.MoreElements;\nimport com.google.common.base.VerifyException;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ElementKind;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.TypeParameterElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.TypeMirror;\n\n/**\n * A wrapper for an {@link ExecutableElement}, representing a static method or a constructor. This\n * wrapper then allows us to attach additional information, such as which parameters have Kotlin\n * defaults.\n */\nclass Executable {\n  private final ExecutableElement executableElement;\n\n  private final ImmutableList<VariableElement> parameters;\n  private final ImmutableSet<String> optionalParameters;\n  private final ImmutableList<TypeParameterElement> typeParameters;\n\n  private Executable(ExecutableElement executableElement, ImmutableSet<String> optionalParameters) {\n    this.executableElement = executableElement;\n    this.parameters = ImmutableList.copyOf(executableElement.getParameters());\n    this.optionalParameters = optionalParameters;\n\n    switch (executableElement.getKind()) {\n      case CONSTRUCTOR:\n        // A constructor can have its own type parameters, in addition to any that its containing\n        // class has. That's pretty unusual, but we allow it, requiring the builder to have type\n        // parameters that are the concatenation of the class's and the constructor's.\n        TypeElement container = MoreElements.asType(executableElement.getEnclosingElement());\n        this.typeParameters =\n            ImmutableList.<TypeParameterElement>builder()\n                .addAll(container.getTypeParameters())\n                .addAll(executableElement.getTypeParameters())\n                .build();\n        break;\n      case METHOD:\n        this.typeParameters = ImmutableList.copyOf(executableElement.getTypeParameters());\n        break;\n      default:\n        throw new VerifyException(\"Unexpected executable kind \" + executableElement.getKind());\n    }\n  }\n\n  static Executable of(ExecutableElement executableElement) {\n    return of(executableElement, ImmutableSet.of());\n  }\n\n  static Executable of(\n      ExecutableElement executableElement, ImmutableSet<String> optionalParameters) {\n    return new Executable(executableElement, optionalParameters);\n  }\n\n  ExecutableElement executableElement() {\n    return executableElement;\n  }\n\n  ImmutableList<VariableElement> parameters() {\n    return parameters;\n  }\n\n  ImmutableList<String> parameterNames() {\n    return parameters.stream().map(v -> v.getSimpleName().toString()).collect(toImmutableList());\n  }\n\n  boolean isOptional(String parameterName) {\n    return optionalParameters.contains(parameterName);\n  }\n\n  boolean hasOptionalParameters() {\n    return !optionalParameters.isEmpty();\n  }\n\n  ImmutableList<TypeParameterElement> typeParameters() {\n    return typeParameters;\n  }\n\n  TypeMirror builtType() {\n    switch (executableElement.getKind()) {\n      case CONSTRUCTOR:\n        return executableElement.getEnclosingElement().asType();\n      case METHOD:\n        return executableElement.getReturnType();\n      default:\n        throw new VerifyException(\"Unexpected executable kind \" + executableElement.getKind());\n    }\n  }\n\n  /**\n   * The Java code to invoke this constructor or method, up to just before the opening {@code (}.\n   */\n  String invoke() {\n    TypeElement enclosing = MoreElements.asType(executableElement.getEnclosingElement());\n    String type = TypeEncoder.encodeRaw(enclosing.asType());\n    switch (executableElement.getKind()) {\n      case CONSTRUCTOR:\n        boolean generic = !enclosing.getTypeParameters().isEmpty();\n        String typeParams = generic ? \"<>\" : \"\";\n        return \"new \" + type + typeParams;\n      case METHOD:\n        return type + \".\" + executableElement.getSimpleName();\n      default:\n        throw new VerifyException(\"Unexpected executable kind \" + executableElement.getKind());\n    }\n  }\n\n  // Used in error messages, for example if more than one constructor matches your setters.\n  @Override\n  public String toString() {\n    ExecutableElement executable = executableElement;\n    Element nameSource =\n        executable.getKind() == ElementKind.CONSTRUCTOR\n            ? executable.getEnclosingElement()\n            : executable;\n    return nameSource.getSimpleName()\n        + executable.getParameters().stream()\n            .map(v -> v.asType() + \" \" + v.getSimpleName())\n            .collect(joining(\", \", \"(\", \")\"));\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/ExtensionContext.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.auto.value.processor.ClassNames.COPY_ANNOTATIONS_NAME;\n\nimport com.google.auto.value.extension.AutoValueExtension;\nimport com.google.auto.value.extension.AutoValueExtension.BuilderContext;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Maps;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.Set;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.TypeMirror;\n\nclass ExtensionContext implements AutoValueExtension.Context {\n\n  private final AutoValueProcessor autoValueProcessor;\n  private final ProcessingEnvironment processingEnvironment;\n  private final TypeElement autoValueClass;\n  private final ImmutableMap<String, ExecutableElement> properties;\n  private final ImmutableMap<String, AnnotatedTypeMirror> propertyTypes;\n  private final ImmutableSet<ExecutableElement> abstractMethods;\n  private final ImmutableSet<ExecutableElement> builderAbstractMethods;\n  private Optional<BuilderContext> builderContext = Optional.empty();\n\n  ExtensionContext(\n      AutoValueProcessor autoValueProcessor,\n      ProcessingEnvironment processingEnvironment,\n      TypeElement autoValueClass,\n      ImmutableMap<String, ExecutableElement> properties,\n      ImmutableMap<ExecutableElement, AnnotatedTypeMirror> propertyMethodsAndTypes,\n      ImmutableSet<ExecutableElement> abstractMethods,\n      ImmutableSet<ExecutableElement> builderAbstractMethods) {\n    this.autoValueProcessor = autoValueProcessor;\n    this.processingEnvironment = processingEnvironment;\n    this.autoValueClass = autoValueClass;\n    this.properties = properties;\n    this.propertyTypes =\n        ImmutableMap.copyOf(Maps.transformValues(properties, propertyMethodsAndTypes::get));\n    this.abstractMethods = abstractMethods;\n    this.builderAbstractMethods = builderAbstractMethods;\n  }\n\n  void setBuilderContext(BuilderContext builderContext) {\n    this.builderContext = Optional.of(builderContext);\n  }\n\n  @Override\n  public ProcessingEnvironment processingEnvironment() {\n    return processingEnvironment;\n  }\n\n  @Override\n  public String packageName() {\n    return TypeSimplifier.packageNameOf(autoValueClass);\n  }\n\n  @Override\n  public TypeElement autoValueClass() {\n    return autoValueClass;\n  }\n\n  @Override\n  public String finalAutoValueClassName() {\n    return AutoValueProcessor.generatedSubclassName(autoValueClass, 0);\n  }\n\n  @Override\n  public Map<String, ExecutableElement> properties() {\n    return properties;\n  }\n\n  @Override\n  public Map<String, TypeMirror> propertyTypes() {\n    return Maps.transformValues(propertyTypes, AnnotatedTypeMirror::getType);\n  }\n\n  @Override\n  public Set<ExecutableElement> abstractMethods() {\n    return abstractMethods;\n  }\n\n  @Override\n  public Set<ExecutableElement> builderAbstractMethods() {\n    return builderAbstractMethods;\n  }\n\n  @Override\n  public List<AnnotationMirror> classAnnotationsToCopy(TypeElement classToCopyFrom) {\n    // Only copy annotations from a class if it has @AutoValue.CopyAnnotations.\n    if (!AutoValueishProcessor.hasAnnotationMirror(classToCopyFrom, COPY_ANNOTATIONS_NAME)) {\n      return ImmutableList.of();\n    }\n\n    ImmutableSet<String> excludedAnnotations =\n        ImmutableSet.<String>builder()\n            .addAll(AutoValueishProcessor.getExcludedAnnotationClassNames(classToCopyFrom))\n            .addAll(AutoValueishProcessor.getAnnotationsMarkedWithInherited(classToCopyFrom))\n            //\n            // Kotlin classes have an intrinsic @Metadata annotation generated\n            // onto them by kotlinc. This annotation is specific to the annotated\n            // class and should not be implicitly copied. Doing so can mislead\n            // static analysis or metaprogramming tooling that reads the data\n            // contained in these annotations.\n            //\n            // It may be surprising to see AutoValue classes written in Kotlin\n            // when they could be written as Kotlin data classes, but this can\n            // come up in cases where consumers rely on AutoValue features or\n            // extensions that are not available in data classes.\n            //\n            // See: https://github.com/google/auto/issues/1087\n            //\n            .add(ClassNames.KOTLIN_METADATA_NAME)\n            .build();\n\n    return autoValueProcessor.annotationsToCopy(\n        autoValueClass, classToCopyFrom, excludedAnnotations);\n  }\n\n  @Override\n  public List<AnnotationMirror> methodAnnotationsToCopy(ExecutableElement method) {\n    return autoValueProcessor.propertyMethodAnnotations(autoValueClass, method);\n  }\n\n  @Override\n  public Optional<BuilderContext> builder() {\n    return builderContext;\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/ForwardingClassGenerator.java",
    "content": "/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.auto.common.MoreTypes.asArray;\nimport static com.google.auto.common.MoreTypes.asTypeElement;\nimport static java.util.stream.Collectors.joining;\nimport static org.objectweb.asm.ClassWriter.COMPUTE_MAXS;\nimport static org.objectweb.asm.Opcodes.ACC_FINAL;\nimport static org.objectweb.asm.Opcodes.ACC_STATIC;\nimport static org.objectweb.asm.Opcodes.ACC_SUPER;\nimport static org.objectweb.asm.Opcodes.ALOAD;\nimport static org.objectweb.asm.Opcodes.ARETURN;\nimport static org.objectweb.asm.Opcodes.DLOAD;\nimport static org.objectweb.asm.Opcodes.DUP;\nimport static org.objectweb.asm.Opcodes.FLOAD;\nimport static org.objectweb.asm.Opcodes.ILOAD;\nimport static org.objectweb.asm.Opcodes.INVOKESPECIAL;\nimport static org.objectweb.asm.Opcodes.LLOAD;\nimport static org.objectweb.asm.Opcodes.NEW;\nimport static org.objectweb.asm.Opcodes.V1_8;\n\nimport com.google.auto.common.MoreElements;\nimport com.google.common.collect.ImmutableList;\nimport javax.lang.model.element.NestingKind;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.TypeParameterElement;\nimport javax.lang.model.type.ArrayType;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.PrimitiveType;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.type.TypeVariable;\nimport javax.lang.model.type.WildcardType;\nimport javax.lang.model.util.SimpleTypeVisitor8;\nimport javax.lang.model.util.Types;\nimport org.jspecify.annotations.Nullable;\nimport org.objectweb.asm.ClassWriter;\nimport org.objectweb.asm.MethodVisitor;\nimport org.objectweb.asm.signature.SignatureVisitor;\nimport org.objectweb.asm.signature.SignatureWriter;\n\n/**\n * Generates a class that invokes the constructor of another class.\n *\n * <p>The point here is that the constructor might be synthetic, in which case it can't be called\n * directly from Java source code. Say we want to call the constructor {@code ConstructMe(int,\n * String, long)} with parameters {@code 1, \"2\", 3L}. If the constructor is synthetic, then Java\n * source code can't just do {@code new ConstructMe(1, \"2\", 3L)}. So this class allows you to\n * generate a class file, say {@code Forwarder}, that is basically what you would get if you could\n * compile this:\n *\n * <pre>{@code\n * final class Forwarder {\n *   private Forwarder() {}\n *\n *   static ConstructMe of(int a, String b, long c) {\n *     return new ConstructMe(a, b, c);\n *   }\n * }\n * }</pre>\n *\n * <p>Because the class file is assembled directly, rather than being produced by the Java compiler,\n * it <i>can</i> call the synthetic constructor. Then regular Java source code can do {@code\n * Forwarder.of(1, \"2\", 3L)} to call the constructor.\n */\nfinal class ForwardingClassGenerator {\n  private final Types typeUtils;\n\n  ForwardingClassGenerator(Types typeUtils) {\n    this.typeUtils = typeUtils;\n  }\n\n  /**\n   * Assembles a class with a static method {@code of} that calls the constructor of another class\n   * with the same parameters.\n   *\n   * <p>It would be simpler if we could just pass in an {@code ExecutableElement} representing the\n   * constructor, but if it is synthetic then it won't be visible to the {@code javax.lang.model}\n   * APIs. So we have to pass the constructed type and the constructor parameter types separately.\n   *\n   * @param forwardingClassName the fully-qualified name of the class to generate\n   * @param classToConstruct the type whose constructor will be invoked ({@code ConstructMe} in the\n   *     example above)\n   * @param constructorParameters the types of the constructor parameters, which will also be the\n   *     types of the generated {@code of} method\n   * @return a byte array making up the new class file\n   */\n  byte[] makeConstructorForwarder(\n      String forwardingClassName,\n      DeclaredType classToConstruct,\n      ImmutableList<TypeMirror> constructorParameters) {\n\n    ClassWriter classWriter = new ClassWriter(COMPUTE_MAXS);\n    classWriter.visit(\n        V1_8,\n        ACC_FINAL | ACC_SUPER,\n        internalName(forwardingClassName),\n        null,\n        \"java/lang/Object\",\n        null);\n    classWriter.visitSource(forwardingClassName, null);\n\n    // Generate the `of` method.\n    String parameterSignature =\n        constructorParameters.stream()\n            .map(typeUtils::erasure)\n            .map(ForwardingClassGenerator::signatureEncoding)\n            .collect(joining(\"\"));\n    String internalClassToConstruct = internalName(asTypeElement(classToConstruct));\n    String ofMethodSignature = \"(\" + parameterSignature + \")L\" + internalClassToConstruct + \";\";\n    MethodVisitor ofMethodVisitor =\n        classWriter.visitMethod(\n            ACC_STATIC,\n            \"of\",\n            ofMethodSignature,\n            genericMethodSignature(asTypeElement(classToConstruct), constructorParameters),\n            null);\n    ofMethodVisitor.visitCode();\n\n    // The remaining instructions are basically what ASMifier generates for a class like the\n    // `Forwarder` class in the example above.\n    ofMethodVisitor.visitTypeInsn(NEW, internalClassToConstruct);\n    ofMethodVisitor.visitInsn(DUP);\n\n    int local = 0;\n    for (TypeMirror type : constructorParameters) {\n      ofMethodVisitor.visitVarInsn(loadInstruction(type), local);\n      local += localSize(type);\n    }\n    String constructorToCallSignature = \"(\" + parameterSignature + \")V\";\n    ofMethodVisitor.visitMethodInsn(\n        INVOKESPECIAL,\n        internalClassToConstruct,\n        \"<init>\",\n        constructorToCallSignature,\n        /* isInterface= */ false);\n\n    ofMethodVisitor.visitInsn(ARETURN);\n    ofMethodVisitor.visitMaxs(0, 0);\n    ofMethodVisitor.visitEnd();\n    classWriter.visitEnd();\n    return classWriter.toByteArray();\n  }\n\n  /**\n   * If the given type is generic, returns a string representing the generic signature of the\n   * constructor, which will also be the generic signature of the generated {@code of} method.\n   * Otherwise returns null.\n   *\n   * <p>This is surprisingly complicated. It would be easier, if a bit less clean, just to return\n   * the raw type in the {@code of} method and suppress {@code unchecked} warnings at the call site.\n   */\n  private @Nullable String genericMethodSignature(\n      TypeElement type, ImmutableList<TypeMirror> constructorParameters) {\n    if (type.getTypeParameters().isEmpty()) {\n      return null;\n    }\n    SignatureWriter writer = new SignatureWriter();\n    for (TypeParameterElement param : type.getTypeParameters()) {\n      writer.visitFormalTypeParameter(param.getSimpleName().toString());\n      for (TypeMirror bound : param.getBounds()) {\n        if (typeUtils.asElement(bound).getKind().isClass()) {\n          bound.accept(TYPE_MIRROR_TO_SIGNATURE_VISITOR, writer.visitClassBound());\n        } else {\n          bound.accept(TYPE_MIRROR_TO_SIGNATURE_VISITOR, writer.visitInterfaceBound());\n        }\n      }\n    }\n    for (TypeMirror param : constructorParameters) {\n      param.accept(TYPE_MIRROR_TO_SIGNATURE_VISITOR, writer.visitParameterType());\n    }\n    type.asType().accept(TYPE_MIRROR_TO_SIGNATURE_VISITOR, writer.visitReturnType());\n    return writer.toString();\n  }\n\n  private static class TypeMirrorToSignatureVisitor\n      extends SimpleTypeVisitor8<Void, SignatureVisitor> {\n    @Override\n    public Void visitPrimitive(PrimitiveType t, SignatureVisitor v) {\n      v.visitBaseType(signatureEncoding(t).charAt(0));\n      return null;\n    }\n\n    @Override\n    public Void visitArray(ArrayType t, SignatureVisitor v) {\n      SignatureVisitor componentVisitor = v.visitArrayType();\n      t.getComponentType().accept(this, componentVisitor);\n      return null;\n    }\n\n    @Override\n    public Void visitDeclared(DeclaredType t, SignatureVisitor v) {\n      TypeElement element = asTypeElement(t);\n      v.visitClassType(internalName(element));\n      for (TypeMirror arg : t.getTypeArguments()) {\n        arg.accept(TypeArgumentVisitor.INSTANCE, v);\n      }\n      v.visitEnd();\n      return null;\n    }\n\n    @Override\n    public Void visitTypeVariable(TypeVariable t, SignatureVisitor v) {\n      v.visitTypeVariable(t.asElement().getSimpleName().toString());\n      return null;\n    }\n\n    @Override\n    protected Void defaultAction(TypeMirror t, SignatureVisitor v) {\n      throw new IllegalArgumentException(\"Unexpected type \" + t);\n    }\n  }\n\n  private static class TypeArgumentVisitor extends SimpleTypeVisitor8<Void, SignatureVisitor> {\n    static final TypeArgumentVisitor INSTANCE = new TypeArgumentVisitor();\n\n    @Override\n    public Void visitWildcard(WildcardType t, SignatureVisitor v) {\n      if (t.getExtendsBound() != null) {\n        t.getExtendsBound().accept(TYPE_MIRROR_TO_SIGNATURE_VISITOR, v.visitTypeArgument('+'));\n      } else if (t.getSuperBound() != null) {\n        t.getSuperBound().accept(TYPE_MIRROR_TO_SIGNATURE_VISITOR, v.visitTypeArgument('-'));\n      } else {\n        v.visitTypeArgument();\n      }\n      return null;\n    }\n\n    @Override\n    protected Void defaultAction(TypeMirror e, SignatureVisitor v) {\n      e.accept(TYPE_MIRROR_TO_SIGNATURE_VISITOR, v.visitTypeArgument('='));\n      return null;\n    }\n  }\n\n  private static final TypeMirrorToSignatureVisitor TYPE_MIRROR_TO_SIGNATURE_VISITOR =\n      new TypeMirrorToSignatureVisitor();\n\n  /** The bytecode instruction that copies a parameter of the given type onto the JVM stack. */\n  private int loadInstruction(TypeMirror type) {\n    switch (typeUtils.erasure(type).getKind()) {\n      case DECLARED:\n      case ARRAY:\n        return ALOAD;\n      case LONG:\n        return LLOAD;\n      case FLOAT:\n        return FLOAD;\n      case DOUBLE:\n        return DLOAD;\n      case BYTE:\n      case SHORT:\n      case CHAR:\n      case INT:\n      case BOOLEAN:\n        // These are all represented as int local variables.\n        return ILOAD;\n      default:\n        // We have erased the TypeMirror so we shouldn't be seeing type variables or whatever.\n        throw new IllegalArgumentException(\"Unexpected type \" + type);\n    }\n  }\n\n  /**\n   * The size in the local variable array of a value of the given type. A quirk of the JVM means\n   * that long and double variables each take up two consecutive slots in the local variable array.\n   * (The first n local variables are the parameters, so we need to know their sizes when iterating\n   * over them.)\n   */\n  private static int localSize(TypeMirror type) {\n    switch (type.getKind()) {\n      case LONG:\n      case DOUBLE:\n        return 2;\n      default:\n        return 1;\n    }\n  }\n\n  private static String internalName(String className) {\n    return className.replace('.', '/');\n  }\n\n  /**\n   * Given a class like {@code foo.bar.Outer.Inner}, produces a string like {@code\n   * \"foo/bar/Outer$Inner\"}, which is the way the class is referenced in the JVM.\n   */\n  private static String internalName(TypeElement typeElement) {\n    if (typeElement.getNestingKind().equals(NestingKind.MEMBER)) {\n      TypeElement enclosing = MoreElements.asType(typeElement.getEnclosingElement());\n      return internalName(enclosing) + \"$\" + typeElement.getSimpleName();\n    }\n    return internalName(typeElement.getQualifiedName().toString());\n  }\n\n  private static String signatureEncoding(TypeMirror type) {\n    switch (type.getKind()) {\n      case ARRAY:\n        return \"[\" + signatureEncoding(asArray(type).getComponentType());\n      case BYTE:\n        return \"B\";\n      case SHORT:\n        return \"S\";\n      case INT:\n        return \"I\";\n      case LONG:\n        return \"J\";\n      case FLOAT:\n        return \"F\";\n      case DOUBLE:\n        return \"D\";\n      case CHAR:\n        return \"C\";\n      case BOOLEAN:\n        return \"Z\";\n      case DECLARED:\n        return \"L\" + internalName(asTypeElement(type)) + \";\";\n      default:\n        throw new AssertionError(\"Bad signature type \" + type);\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/GwtCompatibility.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport java.util.List;\nimport java.util.Optional;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.Name;\nimport javax.lang.model.element.TypeElement;\n\nclass GwtCompatibility {\n  private final Optional<AnnotationMirror> gwtCompatibleAnnotation;\n\n  GwtCompatibility(TypeElement type) {\n    Optional<AnnotationMirror> gwtCompatibleAnnotation = Optional.empty();\n    List<? extends AnnotationMirror> annotations = type.getAnnotationMirrors();\n    for (AnnotationMirror annotation : annotations) {\n      Name name = annotation.getAnnotationType().asElement().getSimpleName();\n      if (name.contentEquals(\"GwtCompatible\")) {\n        gwtCompatibleAnnotation = Optional.of(annotation);\n      }\n    }\n    this.gwtCompatibleAnnotation = gwtCompatibleAnnotation;\n  }\n\n  Optional<AnnotationMirror> gwtCompatibleAnnotation() {\n    return gwtCompatibleAnnotation;\n  }\n\n  String gwtCompatibleAnnotationString() {\n    return gwtCompatibleAnnotation.map(AnnotationOutput::sourceFormForAnnotation).orElse(\"\");\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/GwtSerialization.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static java.nio.charset.StandardCharsets.UTF_8;\nimport static java.util.stream.Collectors.toList;\n\nimport com.google.auto.common.AnnotationMirrors;\nimport com.google.auto.value.processor.AutoValueishProcessor.GetterProperty;\nimport com.google.auto.value.processor.PropertyBuilderClassifier.PropertyBuilder;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.Multimap;\nimport com.google.escapevelocity.Template;\nimport java.io.IOException;\nimport java.io.Writer;\nimport java.util.List;\nimport java.util.Optional;\nimport java.util.zip.CRC32;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.TypeMirror;\nimport javax.tools.Diagnostic;\nimport javax.tools.JavaFileObject;\n\n/**\n * Generates GWT serialization code for {@code @AutoValue} classes also marked\n * {@code @GwtCompatible(serializable = true)}.\n *\n * @author Éamonn McManus\n */\nclass GwtSerialization {\n  private final GwtCompatibility gwtCompatibility;\n  private final ProcessingEnvironment processingEnv;\n  private final TypeElement type;\n\n  GwtSerialization(\n      GwtCompatibility gwtCompatibility, ProcessingEnvironment processingEnv, TypeElement type) {\n    this.gwtCompatibility = gwtCompatibility;\n    this.processingEnv = processingEnv;\n    this.type = type;\n  }\n\n  private boolean shouldWriteGwtSerializer() {\n    Optional<AnnotationMirror> optionalGwtCompatible = gwtCompatibility.gwtCompatibleAnnotation();\n    if (optionalGwtCompatible.isPresent()) {\n      AnnotationMirror gwtCompatible = optionalGwtCompatible.get();\n      return AnnotationMirrors.getAnnotationValuesWithDefaults(gwtCompatible).entrySet().stream()\n          .anyMatch(\n              e ->\n                  e.getKey().getSimpleName().contentEquals(\"serializable\")\n                      && e.getValue().getValue().equals(true));\n    }\n    return false;\n  }\n\n  /**\n   * Writes the GWT serializer for the given type, if appropriate. An {@code @AutoValue} class gets\n   * a GWT serializer if it is annotated with {@code @GwtCompatible(serializable = true)}, where the\n   * {@code @GwtCompatible} annotation can come from any package.\n   *\n   * <p>If the type is com.example.Foo then the generated AutoValue subclass is\n   * com.example.AutoValue_Foo and the GWT serializer is\n   * com.example.AutoValue_Foo_CustomFieldSerializer.\n   *\n   * @param autoVars the template variables defined for this type.\n   * @param finalSubclass the simple name of the AutoValue class being generated, AutoValue_Foo in\n   *     the example.\n   */\n  void maybeWriteGwtSerializer(AutoValueTemplateVars autoVars, String finalSubclass) {\n    if (shouldWriteGwtSerializer()) {\n      GwtTemplateVars vars = new GwtTemplateVars();\n      vars.pkg = autoVars.pkg;\n      vars.subclass = finalSubclass;\n      vars.formalTypes = autoVars.formalTypes;\n      vars.actualTypes = autoVars.actualTypes;\n      vars.useBuilder = !autoVars.builderTypeName.isEmpty();\n      vars.builderSetters = autoVars.builderSetters;\n      vars.builderPropertyBuilders = autoVars.builderPropertyBuilders;\n      vars.generated = autoVars.generated;\n      String className =\n          (vars.pkg.isEmpty() ? \"\" : vars.pkg + \".\") + vars.subclass + \"_CustomFieldSerializer\";\n      vars.serializerClass = TypeSimplifier.simpleNameOf(className);\n      vars.props =\n          autoVars.props.stream().map(p -> new Property((GetterProperty) p)).collect(toList());\n      vars.classHashString = computeClassHash(autoVars.props, vars.pkg);\n      String text = vars.toText();\n      text = TypeEncoder.decode(text, processingEnv, vars.pkg, type.asType());\n      writeSourceFile(className, text, type);\n    }\n  }\n\n  public static class Property {\n    private final GetterProperty property;\n    private final boolean isCastingUnchecked;\n\n    Property(GetterProperty property) {\n      this.property = property;\n      this.isCastingUnchecked = TypeSimplifier.isCastingUnchecked(property.getTypeMirror());\n    }\n\n    @Override\n    public String toString() {\n      return property.toString();\n    }\n\n    public String getGetter() {\n      return property.getGetter();\n    }\n\n    public String getType() {\n      return property.getType();\n    }\n\n    public String getName() {\n      return property.getName();\n    }\n\n    /**\n     * Returns the suffix in serializer method names for values of the given type. For example, if\n     * the type is \"int\" then the returned value will be \"Int\" because the serializer methods are\n     * called readInt and writeInt. There are methods for all primitive types and String; every\n     * other type uses readObject and writeObject.\n     */\n    public String getGwtType() {\n      TypeMirror typeMirror = property.getTypeMirror();\n      String type = typeMirror.toString();\n      if (property.getKind().isPrimitive()) {\n        return Character.toUpperCase(type.charAt(0)) + type.substring(1);\n      } else if (type.equals(\"java.lang.String\")) {\n        return \"String\";\n      } else {\n        return \"Object\";\n      }\n    }\n\n    /**\n     * Returns a string to be inserted before the call to the readFoo() call so that the expression\n     * can be assigned to the given type. For primitive types and String, the readInt() etc methods\n     * already return the right type so the string is empty. For other types, the string is a cast\n     * like \"(Foo) \".\n     */\n    public String getGwtCast() {\n      if (property.getKind().isPrimitive() || getType().equals(\"String\")) {\n        return \"\";\n      } else {\n        return \"(\" + getType() + \") \";\n      }\n    }\n\n    public boolean isCastingUnchecked() {\n      return isCastingUnchecked;\n    }\n  }\n\n  @SuppressWarnings(\"unused\") // some fields are only read through reflection\n  static class GwtTemplateVars extends TemplateVars {\n    /** The properties defined by the parent class's abstract methods. */\n    List<Property> props;\n\n    /**\n     * The package of the class with the {@code @AutoValue} annotation and its generated subclass.\n     */\n    String pkg;\n\n    /** The simple name of the generated subclass. */\n    String subclass;\n\n    /**\n     * The formal generic signature of the class with the {@code @AutoValue} annotation and its\n     * generated subclass. This is empty, or contains type variables with optional bounds, for\n     * example {@code <K, V extends K>}.\n     */\n    String formalTypes;\n\n    /**\n     * The generic signature used by the generated subclass for its superclass reference. This is\n     * empty, or contains only type variables with no bounds, for example {@code <K, V>}.\n     */\n    String actualTypes;\n\n    /** True if the {@code @AutoValue} class is constructed using a generated builder. */\n    Boolean useBuilder;\n\n    /**\n     * A multimap from property names (like foo) to the corresponding setter methods (foo or\n     * setFoo).\n     */\n    Multimap<String, BuilderSpec.PropertySetter> builderSetters;\n\n    /**\n     * A map from property names to information about the associated property builder. A property\n     * called foo (defined by a method foo() or getFoo()) can have a property builder called\n     * fooBuilder(). The type of foo must be a type that has an associated builder following certain\n     * conventions. Guava immutable types such as ImmutableList follow those conventions, as do many\n     * {@code @AutoValue} types.\n     */\n    ImmutableMap<String, PropertyBuilder> builderPropertyBuilders = ImmutableMap.of();\n\n    /** The simple name of the generated GWT serializer class. */\n    String serializerClass;\n\n    /**\n     * The encoding of the {@code Generated} class. Empty if no {@code Generated} class is\n     * available.\n     */\n    String generated;\n\n    /** A string that should change if any salient details of the serialized class change. */\n    String classHashString;\n\n    private static final Template TEMPLATE = parsedTemplateForResource(\"gwtserializer.vm\");\n\n    @Override\n    Template parsedTemplate() {\n      return TEMPLATE;\n    }\n  }\n\n  private void writeSourceFile(String className, String text, TypeElement originatingType) {\n    try {\n      JavaFileObject sourceFile =\n          processingEnv.getFiler().createSourceFile(className, originatingType);\n      try (Writer writer = sourceFile.openWriter()) {\n        writer.write(text);\n      }\n    } catch (IOException e) {\n      processingEnv\n          .getMessager()\n          .printMessage(\n              Diagnostic.Kind.WARNING, \"Could not write generated class \" + className + \": \" + e);\n      // A warning rather than an error for the reason explained in\n      // AutoValueishProcessor.writeSourceFile.\n    }\n  }\n\n  // Compute a hash that is guaranteed to change if the names, types, or order of the fields\n  // change. We use TypeEncoder so that we can get a defined string for types, since\n  // TypeMirror.toString() isn't guaranteed to remain the same.\n  private String computeClassHash(Iterable<AutoValueishProcessor.Property> props, String pkg) {\n    CRC32 crc = new CRC32();\n    String encodedType = TypeEncoder.encode(type.asType()) + \":\";\n    String decodedType = TypeEncoder.decode(encodedType, processingEnv, \"\", null);\n    if (!decodedType.startsWith(pkg)) {\n      // This is for compatibility with the way an earlier version did things. Preserving hash\n      // codes probably isn't vital, since client and server should be in sync.\n      decodedType = pkg + \".\" + decodedType;\n    }\n    crc.update(decodedType.getBytes(UTF_8));\n    for (AutoValueishProcessor.Property prop : props) {\n      String encodedProp = prop + \":\" + TypeEncoder.encode(prop.getTypeMirror()) + \";\";\n      String decodedProp = TypeEncoder.decode(encodedProp, processingEnv, pkg, null);\n      crc.update(decodedProp.getBytes(UTF_8));\n    }\n    return String.format(\"%08x\", crc.getValue());\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/JavaScanner.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\n/**\n * A simplistic Java scanner. This scanner returns a sequence of tokens that can be used to\n * reconstruct the source code. Since the source code is coming from a string, the scanner in fact\n * just returns token boundaries rather than the tokens themselves.\n *\n * <p>We are not dealing with arbitrary user code so we can assume there are no exotic things like\n * tabs or Unicode escapes that resolve into quotes. The purpose of the scanner here is to return a\n * sequence of offsets that split the string up in a way that allows us to work with spaces without\n * having to worry whether they are inside strings or comments. The particular properties we use are\n * that every string and character literal and every comment is a single token; every newline plus\n * all following indentation is a single token; and every other string of consecutive spaces outside\n * a comment or literal is a single token. That means that we can safely compress a token that\n * starts with a space into a single space, without falsely removing indentation or changing the\n * contents of strings.\n *\n * <p>In addition to real Java syntax, this scanner recognizes tokens of the form {@code `text`},\n * which are used in the templates to wrap fully-qualified type names, so that they can be extracted\n * and replaced by imported names if possible.\n *\n * @author Éamonn McManus\n */\nclass JavaScanner {\n  private final String s;\n\n  JavaScanner(String s) {\n    this.s = s.endsWith(\"\\n\") ? s : (s + '\\n');\n    // This allows us to avoid checking for the end of the string in most cases.\n  }\n\n  /**\n   * Returns the string being scanned, which is either the original input string or that string plus\n   * a newline.\n   */\n  String string() {\n    return s;\n  }\n\n  /** Returns the position at which this token ends and the next token begins. */\n  int tokenEnd(int start) {\n    if (start >= s.length()) {\n      return s.length();\n    }\n    switch (s.charAt(start)) {\n      case ' ':\n      case '\\n':\n        return spaceEnd(start);\n      case '/':\n        if (s.charAt(start + 1) == '*') {\n          return blockCommentEnd(start);\n        } else if (s.charAt(start + 1) == '/') {\n          return lineCommentEnd(start);\n        } else {\n          return start + 1;\n        }\n      case '\\'':\n      case '\"':\n      case '`':\n        return quoteEnd(start);\n      default:\n        // Every other character is considered to be its own token.\n        return start + 1;\n    }\n  }\n\n  private int spaceEnd(int start) {\n    assert s.charAt(start) == ' ' || s.charAt(start) == '\\n';\n    int i;\n    for (i = start + 1; i < s.length() && s.charAt(i) == ' '; i++) {}\n    return i;\n  }\n\n  private int blockCommentEnd(int start) {\n    assert s.charAt(start) == '/' && s.charAt(start + 1) == '*';\n    int i;\n    for (i = start + 2; s.charAt(i) != '*' || s.charAt(i + 1) != '/'; i++) {}\n    return i + 2;\n  }\n\n  private int lineCommentEnd(int start) {\n    assert s.charAt(start) == '/' && s.charAt(start + 1) == '/';\n    int end = s.indexOf('\\n', start + 2);\n    assert end > 0;\n    return end;\n  }\n\n  private int quoteEnd(int start) {\n    char quote = s.charAt(start);\n    assert quote == '\\'' || quote == '\"' || quote == '`';\n    int i;\n    for (i = start + 1; s.charAt(i) != quote; i++) {\n      if (s.charAt(i) == '\\\\') {\n        i++;\n      }\n    }\n    return i + 1;\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/KotlinMetadata.java",
    "content": "/*\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.auto.common.MoreTypes.asTypeElement;\nimport static com.google.auto.value.processor.ClassNames.KOTLIN_METADATA_NAME;\nimport static com.google.common.base.Throwables.throwIfUnchecked;\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static com.google.common.collect.ImmutableMap.toImmutableMap;\nimport static com.google.common.collect.ImmutableSet.toImmutableSet;\nimport static java.util.stream.Collectors.toMap;\nimport static javax.lang.model.util.ElementFilter.constructorsIn;\n\nimport com.google.auto.common.AnnotationMirrors;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\n\n/**\n * Utilities for working with Kotlin metadata.\n *\n * <p>We use reflection to avoid referencing the Kotlin metadata API directly. AutoBuilder clients\n * that don't use Kotlin shouldn't have to have the Kotlin runtime on their classpath, even if it is\n * only the annotation-processing classpath.\n */\nfinal class KotlinMetadata {\n  private final ErrorReporter errorReporter;\n  private boolean warnedAboutMissingMetadataApi;\n\n  KotlinMetadata(ErrorReporter errorReporter) {\n    this.errorReporter = errorReporter;\n  }\n\n  /**\n   * Use Kotlin reflection to build {@link Executable} instances for the constructors in {@code\n   * ofClass} that include information about which parameters have default values.\n   *\n   * @param metadata the {@code @kotlin.Metadata} annotation on {@code ofClass}\n   * @param ofClass the class whose constructors should be returned\n   */\n  ImmutableList<Executable> kotlinConstructorsIn(AnnotationMirror metadata, TypeElement ofClass) {\n    if (!KOTLIN_METADATA_AVAILABLE) {\n      if (!warnedAboutMissingMetadataApi) {\n        warnedAboutMissingMetadataApi = true;\n        errorReporter.reportWarning(\n            ofClass,\n            \"[AutoBuilderNoMetadataApi] The Kotlin metadata API (kotlinx.metadata or\"\n                + \" kotlin.metadata) is not available. You may need to add a dependency on\"\n                + \" org.jetbrains.kotlin:kotlin-metadata-jvm.\");\n      }\n      return ImmutableList.of();\n    }\n    try {\n      return kotlinConstructorsFromReflection(metadata, ofClass);\n    } catch (InvocationTargetException e) {\n      throwIfUnchecked(e.getCause());\n      // We don't expect the Kotlin API to throw checked exceptions.\n      throw new LinkageError(e.getMessage(), e);\n    } catch (ReflectiveOperationException e) {\n      throw new LinkageError(e.getMessage(), e);\n    }\n  }\n\n  private static ImmutableList<Executable> kotlinConstructorsFromReflection(\n      AnnotationMirror metadata, TypeElement ofClass) throws ReflectiveOperationException {\n    ImmutableMap<String, AnnotationValue> annotationValues =\n        AnnotationMirrors.getAnnotationValuesWithDefaults(metadata).entrySet().stream()\n            .collect(toImmutableMap(e -> e.getKey().getSimpleName().toString(), e -> e.getValue()));\n    // We match the KmConstructor instances with the ExecutableElement instances based on the\n    // parameter names. We could possibly just assume that the constructors are in the same order.\n    Map<ImmutableSet<String>, ExecutableElement> map =\n        constructorsIn(ofClass.getEnclosedElements()).stream()\n            .collect(toMap(c -> parameterNames(c), c -> c, (a, b) -> a, LinkedHashMap::new));\n    ImmutableMap<ImmutableSet<String>, ExecutableElement> paramNamesToConstructor =\n        ImmutableMap.copyOf(map);\n    KotlinClassHeader header =\n        new KotlinClassHeader(\n            (Integer) annotationValues.get(\"k\").getValue(),\n            intArrayValue(annotationValues.get(\"mv\")),\n            stringArrayValue(annotationValues.get(\"d1\")),\n            stringArrayValue(annotationValues.get(\"d2\")),\n            (String) annotationValues.get(\"xs\").getValue(),\n            (String) annotationValues.get(\"pn\").getValue(),\n            (Integer) annotationValues.get(\"xi\").getValue());\n    KotlinClassMetadata.Class classMetadata = KotlinClassMetadata.readLenient(header);\n    KmClass kmClass = classMetadata.getKmClass();\n    ImmutableList.Builder<Executable> kotlinConstructorsBuilder = ImmutableList.builder();\n    for (KmConstructor constructor : kmClass.getConstructors()) {\n      ImmutableSet.Builder<String> allBuilder = ImmutableSet.builder();\n      ImmutableSet.Builder<String> optionalBuilder = ImmutableSet.builder();\n      for (KmValueParameter param : constructor.getValueParameters()) {\n        String name = param.getName();\n        allBuilder.add(name);\n        if (Attributes.getDeclaresDefaultValue(param)) {\n          optionalBuilder.add(name);\n        }\n      }\n      ImmutableSet<String> optional = optionalBuilder.build();\n      ImmutableSet<String> all = allBuilder.build();\n      ExecutableElement javaConstructor = paramNamesToConstructor.get(all);\n      if (javaConstructor != null) {\n        kotlinConstructorsBuilder.add(Executable.of(javaConstructor, optional));\n      }\n    }\n    return kotlinConstructorsBuilder.build();\n  }\n\n  private static ImmutableSet<String> parameterNames(ExecutableElement executableElement) {\n    return executableElement.getParameters().stream()\n        .map(v -> v.getSimpleName().toString())\n        .collect(toImmutableSet());\n  }\n\n  Optional<AnnotationMirror> kotlinMetadataAnnotation(Element element) {\n    return element.getAnnotationMirrors().stream()\n        .filter(\n            a ->\n                asTypeElement(a.getAnnotationType())\n                    .getQualifiedName()\n                    .contentEquals(KOTLIN_METADATA_NAME))\n        .<AnnotationMirror>map(a -> a) // get rid of that stupid wildcard\n        .findFirst();\n  }\n\n  private static int[] intArrayValue(AnnotationValue value) {\n    @SuppressWarnings(\"unchecked\")\n    List<AnnotationValue> list = (List<AnnotationValue>) value.getValue();\n    return list.stream().mapToInt(v -> (int) v.getValue()).toArray();\n  }\n\n  private static String[] stringArrayValue(AnnotationValue value) {\n    @SuppressWarnings(\"unchecked\")\n    List<AnnotationValue> list = (List<AnnotationValue>) value.getValue();\n    return list.stream().map(AnnotationValue::getValue).toArray(String[]::new);\n  }\n\n  // Wrapper classes for the Kotlin metadata API. These classes have the same names as the ones\n  // from that API (minus the package of course), and use reflection to access the real API. This\n  // allows us to write client code that is essentially the same as if we were using the real API.\n  // Otherwise the logic would be obscured by all the reflective calls.\n\n  private static class KotlinClassHeader {\n    final Object /* KotlinClassHeader */ wrapped;\n\n    KotlinClassHeader(\n        Integer k, int[] mv, String[] d1, String[] d2, String xs, String pn, Integer xi)\n        throws ReflectiveOperationException {\n      this.wrapped = NEW_KOTLIN_CLASS_HEADER.newInstance(k, mv, d1, d2, xs, pn, xi);\n    }\n  }\n\n  @SuppressWarnings({\"JavaLangClash\", \"SameNameButDifferent\"}) // \"Class\"\n  private static class KotlinClassMetadata {\n    static Class readLenient(KotlinClassHeader kotlinClassHeader)\n        throws ReflectiveOperationException {\n      return new Class(KOTLIN_CLASS_METADATA_READ_LENIENT.invoke(null, kotlinClassHeader.wrapped));\n    }\n\n    static class Class {\n      final Object /* KotlinClassMetadata.Class */ wrapped;\n\n      Class(Object /* KotlinClassMetadata.Class */ wrapped) {\n        this.wrapped = wrapped;\n      }\n\n      KmClass getKmClass() throws ReflectiveOperationException {\n        return new KmClass(KOTLIN_CLASS_METADATA_CLASS_GET_KM_CLASS.invoke(wrapped));\n      }\n    }\n  }\n\n  private static class KmClass {\n    final Object /* KmClass */ wrapped;\n\n    KmClass(Object wrapped) {\n      this.wrapped = wrapped;\n    }\n\n    List<KmConstructor> getConstructors() throws ReflectiveOperationException {\n      return ((List<?>) KM_CLASS_GET_CONSTRUCTORS.invoke(wrapped))\n          .stream().map(KmConstructor::new).collect(toImmutableList());\n    }\n  }\n\n  private static class KmConstructor {\n    final Object /* KmConstructor */ wrapped;\n\n    KmConstructor(Object wrapped) {\n      this.wrapped = wrapped;\n    }\n\n    List<KmValueParameter> getValueParameters() throws ReflectiveOperationException {\n      return ((List<?>) KM_CONSTRUCTOR_GET_VALUE_PARAMETERS.invoke(wrapped))\n          .stream().map(KmValueParameter::new).collect(toImmutableList());\n    }\n  }\n\n  private static class KmValueParameter {\n    final Object /* KmValueParameter */ wrapped;\n\n    KmValueParameter(Object wrapped) {\n      this.wrapped = wrapped;\n    }\n\n    String getName() throws ReflectiveOperationException {\n      return (String) KM_VALUE_PARAMETER_GET_NAME.invoke(wrapped);\n    }\n  }\n\n  private static class Attributes {\n    private Attributes() {}\n\n    static boolean getDeclaresDefaultValue(KmValueParameter kmValueParameter)\n        throws ReflectiveOperationException {\n      return (boolean) ATTRIBUTES_GET_DECLARES_DEFAULT_VALUE.invoke(null, kmValueParameter.wrapped);\n    }\n  }\n\n  private static final Constructor<?> NEW_KOTLIN_CLASS_HEADER;\n  private static final Method KOTLIN_CLASS_METADATA_READ_LENIENT;\n  private static final Method KOTLIN_CLASS_METADATA_CLASS_GET_KM_CLASS;\n  private static final Method KM_CLASS_GET_CONSTRUCTORS;\n  private static final Method KM_CONSTRUCTOR_GET_VALUE_PARAMETERS;\n  private static final Method KM_VALUE_PARAMETER_GET_NAME;\n  private static final Method ATTRIBUTES_GET_DECLARES_DEFAULT_VALUE;\n  private static final boolean KOTLIN_METADATA_AVAILABLE;\n\n  static {\n    Constructor<?> newKotlinClassHeader = null;\n    Method kotlinClassMetadataReadLenient = null;\n    Method kotlinClassMetadataClassGetKmClass = null;\n    Method kmClassGetConstructors = null;\n    Method kmConstructorGetValueParameters = null;\n    Method kmValueParameterGetName = null;\n    Method attributeGetDeclaresDefaultValue = null;\n    boolean kotlinMetadataAvailable = false;\n    for (String prefix : new String[] {\"kotlin.metadata.\", \"kotlinx.metadata.\"}) {\n      try {\n        Class<?> kotlinClassHeaderClass = Class.forName(prefix + \"jvm.KotlinClassHeader\");\n        newKotlinClassHeader =\n            kotlinClassHeaderClass.getConstructor(\n                Integer.class,\n                int[].class,\n                String[].class,\n                String[].class,\n                String.class,\n                String.class,\n                Integer.class);\n        Class<?> kotlinClassMetadataClass = Class.forName(prefix + \"jvm.KotlinClassMetadata\");\n        // Load `kotlin.Metadata` in the same classloader as `kotlinClassHeaderClass`. They are\n        // potentially from different artifacts so we could otherwise end up with a\n        // `kotlin.Metadata` that is not actually the type of the `readLenient` parameter because of\n        // differing classloaders.\n        Class<?> kotlinMetadataClass =\n            Class.forName(\"kotlin.Metadata\", false, kotlinClassHeaderClass.getClassLoader());\n        kotlinClassMetadataReadLenient =\n            kotlinClassMetadataClass.getMethod(\"readLenient\", kotlinMetadataClass);\n        Class<?> kotlinClassMetadataClassClass =\n            Class.forName(prefix + \"jvm.KotlinClassMetadata$Class\");\n        Class<?> kmClassClass = Class.forName(prefix + \"KmClass\");\n        kotlinClassMetadataClassGetKmClass = kotlinClassMetadataClassClass.getMethod(\"getKmClass\");\n        kmClassGetConstructors = kmClassClass.getMethod(\"getConstructors\");\n        Class<?> kmConstructorClass = Class.forName(prefix + \"KmConstructor\");\n        kmConstructorGetValueParameters = kmConstructorClass.getMethod(\"getValueParameters\");\n        Class<?> kmValueParameterClass = Class.forName(prefix + \"KmValueParameter\");\n        kmValueParameterGetName = kmValueParameterClass.getMethod(\"getName\");\n        Class<?> attributeClass = Class.forName(prefix + \"Attributes\");\n        attributeGetDeclaresDefaultValue =\n            attributeClass.getMethod(\"getDeclaresDefaultValue\", kmValueParameterClass);\n        kotlinMetadataAvailable = true;\n        break;\n      } catch (ReflectiveOperationException e) {\n        // OK: The metadata API is unavailable with this prefix, and possibly with any prefix.\n      }\n    }\n    NEW_KOTLIN_CLASS_HEADER = newKotlinClassHeader;\n    KOTLIN_CLASS_METADATA_READ_LENIENT = kotlinClassMetadataReadLenient;\n    KOTLIN_CLASS_METADATA_CLASS_GET_KM_CLASS = kotlinClassMetadataClassGetKmClass;\n    KM_CLASS_GET_CONSTRUCTORS = kmClassGetConstructors;\n    KM_CONSTRUCTOR_GET_VALUE_PARAMETERS = kmConstructorGetValueParameters;\n    KM_VALUE_PARAMETER_GET_NAME = kmValueParameterGetName;\n    ATTRIBUTES_GET_DECLARES_DEFAULT_VALUE = attributeGetDeclaresDefaultValue;\n    KOTLIN_METADATA_AVAILABLE = kotlinMetadataAvailable;\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/MethodSignature.java",
    "content": "/*\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.auto.common.MoreTypes.asDeclared;\nimport static com.google.auto.common.MoreTypes.asExecutable;\nimport static com.google.common.collect.ImmutableList.toImmutableList;\n\nimport com.google.common.collect.ImmutableList;\nimport java.util.stream.IntStream;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.ExecutableType;\nimport javax.lang.model.util.Types;\n\n/**\n * Represents the signature of a method: the types of its parameters and of its return value. The\n * types in question are represented using {@link AnnotatedTypeMirror}, which is a {@link\n * TypeMirror} and associated type annotations.\n */\nfinal class MethodSignature {\n  private final ExecutableType originalMethod;\n  private final ExecutableType rewrittenMethod;\n\n  private MethodSignature(ExecutableType originalMethod, ExecutableType rewrittenMethod) {\n    this.originalMethod = originalMethod;\n    this.rewrittenMethod = rewrittenMethod;\n  }\n\n  ImmutableList<AnnotatedTypeMirror> parameterTypes() {\n    return IntStream.range(0, originalMethod.getParameterTypes().size())\n        .mapToObj(\n            i ->\n                new AnnotatedTypeMirror(\n                    originalMethod.getParameterTypes().get(i),\n                    rewrittenMethod.getParameterTypes().get(i)))\n        .collect(toImmutableList());\n  }\n\n  AnnotatedTypeMirror returnType() {\n    return new AnnotatedTypeMirror(originalMethod.getReturnType(), rewrittenMethod.getReturnType());\n  }\n\n  static MethodSignature asMemberOf(Types typeUtils, DeclaredType in, ExecutableElement method) {\n    return new MethodSignature(\n        asExecutable(method.asType()), asExecutable(typeUtils.asMemberOf(in, method)));\n  }\n\n  static MethodSignature asMemberOf(Types typeUtils, TypeElement in, ExecutableElement method) {\n    return asMemberOf(typeUtils, asDeclared(in.asType()), method);\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/MissingTypes.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport java.util.List;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.ArrayType;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.ErrorType;\nimport javax.lang.model.type.IntersectionType;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.type.TypeVariable;\nimport javax.lang.model.type.WildcardType;\nimport javax.lang.model.util.SimpleTypeVisitor8;\n\n/**\n * Handling of undefined types. When we see an undefined type, it might genuinely be undefined, or\n * it might be a type whose source code will be generated later on as part of the same compilation.\n * If we encounter an undefined type in a place where we need to know the type, we throw {@link\n * MissingTypeException}. We then catch that and defer processing for the current class until the\n * next annotation-processing \"round\". If the missing class has been generated in the meanwhile, we\n * may now be able to complete processing. After a round has completed without generating any new\n * source code, if there are still missing types then we report an error.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\nfinal class MissingTypes {\n  private MissingTypes() {}\n\n  /**\n   * Exception thrown in the specific case where processing of a class was abandoned because it\n   * required types that the class references to be present and they were not. This case is handled\n   * specially because it is possible that those types might be generated later during annotation\n   * processing, so we should reattempt the processing of the class in a later annotation processing\n   * round.\n   */\n  @SuppressWarnings(\"serial\")\n  static class MissingTypeException extends RuntimeException {\n    MissingTypeException(ErrorType missingType) {\n      // Although it is not specified as such, in practice ErrorType.toString() is the type name\n      // that appeared in the source code. Showing it here can help in debugging issues with\n      // deferral.\n      super(missingType == null ? \"\" : missingType.toString());\n    }\n  }\n\n  /**\n   * Check that the return type and parameter types of the given method are all defined, and arrange\n   * to defer processing until the next round if not.\n   *\n   * @throws MissingTypeException if the return type or a parameter type of the given method is\n   *     undefined\n   */\n  static void deferIfMissingTypesIn(ExecutableElement method) {\n    MISSING_TYPE_VISITOR.check(method.getReturnType());\n    for (VariableElement param : method.getParameters()) {\n      MISSING_TYPE_VISITOR.check(param.asType());\n    }\n  }\n\n  private static final MissingTypeVisitor MISSING_TYPE_VISITOR = new MissingTypeVisitor();\n\n  private static class MissingTypeVisitor extends SimpleTypeVisitor8<Void, TypeMirrorSet> {\n    // Avoid infinite recursion for a type like `Enum<E extends Enum<E>>` by remembering types that\n    // we have already seen on this visit. Recursion has to go through a declared type, such as Enum\n    // in this example, so in principle it should be enough to check only in visitDeclared. However\n    // Eclipse has a quirk where the second E in `Enum<E extends Enum<E>>` is not the same as the\n    // first, and if you ask for its bounds you will get another `Enum<E>` with a third E. So we\n    // also check in visitTypeVariable. TypeMirrorSet does consider that all these E variables are\n    // the same so infinite recursion is avoided.\n    void check(TypeMirror type) {\n      type.accept(this, new TypeMirrorSet());\n    }\n\n    @Override\n    public Void visitError(ErrorType t, TypeMirrorSet visiting) {\n      throw new MissingTypeException(t);\n    }\n\n    @Override\n    public Void visitArray(ArrayType t, TypeMirrorSet visiting) {\n      return t.getComponentType().accept(this, visiting);\n    }\n\n    @Override\n    public Void visitDeclared(DeclaredType t, TypeMirrorSet visiting) {\n      if (visiting.add(t)) {\n        visitAll(t.getTypeArguments(), visiting);\n      }\n      return null;\n    }\n\n    @Override\n    public Void visitTypeVariable(TypeVariable t, TypeMirrorSet visiting) {\n      if (visiting.add(t)) {\n        t.getLowerBound().accept(this, visiting);\n        t.getUpperBound().accept(this, visiting);\n      }\n      return null;\n    }\n\n    @Override\n    public Void visitWildcard(WildcardType t, TypeMirrorSet visiting) {\n      if (t.getSuperBound() != null) {\n        t.getSuperBound().accept(this, visiting);\n      }\n      if (t.getExtendsBound() != null) {\n        t.getExtendsBound().accept(this, visiting);\n      }\n      return null;\n    }\n\n    @Override\n    public Void visitIntersection(IntersectionType t, TypeMirrorSet visiting) {\n      return visitAll(t.getBounds(), visiting);\n    }\n\n    private Void visitAll(List<? extends TypeMirror> types, TypeMirrorSet visiting) {\n      for (TypeMirror type : types) {\n        type.accept(this, visiting);\n      }\n      return null;\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/Nullables.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static java.util.stream.Collectors.toList;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.common.base.Strings;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Objects;\nimport java.util.Optional;\nimport java.util.stream.Stream;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.AnnotationValue;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.type.ArrayType;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.IntersectionType;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.type.TypeVariable;\nimport javax.lang.model.type.WildcardType;\nimport javax.lang.model.util.SimpleTypeVisitor8;\n\nclass Nullables {\n  /**\n   * If set to a non-empty string, defines which {@code @Nullable} type annotation should be used by\n   * default. If set to an empty string, does not insert {@code @Nullable} unless it is referenced\n   * in the {@code @AutoValue} methods. If unset, defaults to {@value #DEFAULT_NULLABLE}.\n   */\n  static final String NULLABLE_OPTION = \"com.google.auto.value.NullableTypeAnnotation\";\n\n  // We write this using .concat in order to hide it from rewriting rules.\n  private static final String DEFAULT_NULLABLE = \"org\".concat(\".jspecify.annotations.Nullable\");\n\n  private final Optional<AnnotationMirror> nullableTypeAnnotation;\n\n  private Nullables(Optional<AnnotationMirror> nullableTypeAnnotation) {\n    this.nullableTypeAnnotation = nullableTypeAnnotation;\n  }\n\n  /**\n   * Make an instance where the default {@code @Nullable} type annotation is discovered by looking\n   * for methods whose parameter or return types have such an annotation. If there are none, use a\n   * default {@code @Nullable} type annotation if it is available.\n   *\n   * @param methods the methods to examine\n   * @param processingEnv the {@link ProcessingEnvironment}, or null if one is unavailable\n   *     (typically in tests)\n   */\n  static Nullables fromMethods(\n      /* @Nullable */ ProcessingEnvironment processingEnv, Collection<ExecutableElement> methods) {\n    Optional<AnnotationMirror> nullableTypeAnnotation =\n        methods.stream()\n            .flatMap(\n                method ->\n                    Stream.concat(\n                        Stream.of(method.getReturnType()),\n                        method.getParameters().stream().map(Element::asType)))\n            .map(Nullables::nullableIn)\n            .filter(Optional::isPresent)\n            .findFirst()\n            .orElseGet(() -> defaultNullableTypeAnnotation(processingEnv));\n    return new Nullables(nullableTypeAnnotation);\n  }\n\n  /**\n   * Returns a list that is either empty or contains a single element that is an appropriate\n   * {@code @Nullable} type-annotation.\n   */\n  ImmutableList<AnnotationMirror> nullableTypeAnnotations() {\n    return nullableTypeAnnotation.map(ImmutableList::of).orElse(ImmutableList.of());\n  }\n\n  private static Optional<AnnotationMirror> defaultNullableTypeAnnotation(\n      /* @Nullable */ ProcessingEnvironment processingEnv) {\n    if (processingEnv == null) {\n      return Optional.empty();\n    }\n    // -Afoo without `=` sets \"foo\" to null in the getOptions() map.\n    String nullableOption =\n        Strings.nullToEmpty(\n            processingEnv.getOptions().getOrDefault(NULLABLE_OPTION, DEFAULT_NULLABLE));\n    return (!nullableOption.isEmpty()\n            && processingEnv.getSourceVersion().ordinal() >= SourceVersion.RELEASE_8.ordinal())\n        ? Optional.ofNullable(processingEnv.getElementUtils().getTypeElement(nullableOption))\n            .map(t -> annotationMirrorOf(MoreTypes.asDeclared(t.asType())))\n        : Optional.empty();\n  }\n\n  private static AnnotationMirror annotationMirrorOf(DeclaredType annotationType) {\n    return new AnnotationMirror() {\n      @Override\n      public DeclaredType getAnnotationType() {\n        return annotationType;\n      }\n\n      @Override\n      public ImmutableMap<? extends ExecutableElement, ? extends AnnotationValue>\n          getElementValues() {\n        return ImmutableMap.of();\n      }\n    };\n  }\n\n  private static Optional<AnnotationMirror> nullableIn(TypeMirror type) {\n    return new NullableFinder().visit(type);\n  }\n\n  private static Optional<AnnotationMirror> nullableIn(\n      List<? extends AnnotationMirror> annotations) {\n    return annotations.stream()\n        .filter(a -> a.getAnnotationType().asElement().getSimpleName().contentEquals(\"Nullable\"))\n        .map(a -> (AnnotationMirror) a) // get rid of the pesky wildcard\n        .findFirst();\n  }\n\n  private static class NullableFinder extends SimpleTypeVisitor8<Optional<AnnotationMirror>, Void> {\n    private final TypeMirrorSet visiting = new TypeMirrorSet();\n\n    NullableFinder() {\n      super(Optional.empty());\n    }\n\n    // Primitives can't be @Nullable so we don't check that.\n\n    @Override\n    public Optional<AnnotationMirror> visitDeclared(DeclaredType t, Void unused) {\n      if (!visiting.add(t)) {\n        return Optional.empty();\n      }\n      return nullableIn(t.getAnnotationMirrors())\n          .map(Optional::of)\n          .orElseGet(() -> visitAll(t.getTypeArguments()));\n    }\n\n    @Override\n    public Optional<AnnotationMirror> visitTypeVariable(TypeVariable t, Void unused) {\n      if (!visiting.add(t)) {\n        return Optional.empty();\n      }\n      return nullableIn(t.getAnnotationMirrors())\n          .map(Optional::of)\n          .orElseGet(() -> visitAll(ImmutableList.of(t.getUpperBound(), t.getLowerBound())));\n    }\n\n    @Override\n    public Optional<AnnotationMirror> visitArray(ArrayType t, Void unused) {\n      return nullableIn(t.getAnnotationMirrors())\n          .map(Optional::of)\n          .orElseGet(() -> visit(t.getComponentType()));\n    }\n\n    @Override\n    public Optional<AnnotationMirror> visitWildcard(WildcardType t, Void unused) {\n      return nullableIn(t.getAnnotationMirrors())\n          .map(Optional::of)\n          .orElseGet(\n              () ->\n                  visitAll(\n                      Stream.of(t.getExtendsBound(), t.getSuperBound())\n                          .filter(Objects::nonNull)\n                          .collect(toList())));\n    }\n\n    @Override\n    public Optional<AnnotationMirror> visitIntersection(IntersectionType t, Void unused) {\n      return nullableIn(t.getAnnotationMirrors())\n          .map(Optional::of)\n          .orElseGet(() -> visitAll(t.getBounds()));\n    }\n\n    private Optional<AnnotationMirror> visitAll(List<? extends TypeMirror> types) {\n      return types.stream()\n          .map(this::visit)\n          .filter(Optional::isPresent)\n          .findFirst()\n          .orElse(Optional.empty());\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/Optionalish.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport com.google.auto.common.MoreElements;\nimport com.google.auto.common.MoreTypes;\nimport com.google.common.base.Verify;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport java.util.List;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.Types;\n\n/**\n * A wrapper for properties of Optional-like classes. This can be com.google.common.base.Optional,\n * or any of Optional, OptionalDouble, OptionalInt, OptionalLong in java.util.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\npublic class Optionalish {\n  private static final ImmutableSet<String> OPTIONAL_CLASS_NAMES =\n      ImmutableSet.of(\n          \"com.\".concat(\"google.common.base.Optional\"), // subterfuge to foil shading\n          \"java.util.Optional\",\n          \"java.util.OptionalDouble\",\n          \"java.util.OptionalInt\",\n          \"java.util.OptionalLong\");\n\n  private final DeclaredType optionalType;\n  private final String className;\n\n  private Optionalish(DeclaredType optionalType) {\n    this.optionalType = optionalType;\n    this.className = MoreElements.asType(optionalType.asElement()).getQualifiedName().toString();\n  }\n\n  /**\n   * Returns an instance wrapping the given TypeMirror, or null if it is not any kind of Optional.\n   *\n   * @param type the TypeMirror for the original optional type, for example {@code\n   *     Optional<String>}.\n   */\n  static Optionalish createIfOptional(TypeMirror type) {\n    if (isOptional(type)) {\n      return new Optionalish(MoreTypes.asDeclared(type));\n    } else {\n      return null;\n    }\n  }\n\n  static boolean isOptional(TypeMirror type) {\n    if (type.getKind() != TypeKind.DECLARED) {\n      return false;\n    }\n    DeclaredType declaredType = MoreTypes.asDeclared(type);\n    TypeElement typeElement = MoreElements.asType(declaredType.asElement());\n    return OPTIONAL_CLASS_NAMES.contains(typeElement.getQualifiedName().toString())\n        && typeElement.getTypeParameters().size() == declaredType.getTypeArguments().size();\n  }\n\n  /**\n   * Returns a string representing the raw type of this Optional. This will typically be just {@code\n   * \"Optional\"}, but it might be {@code \"OptionalInt\"} or {@code \"java.util.Optional\"} for example.\n   */\n  public String getRawType() {\n    return TypeEncoder.encodeRaw(optionalType);\n  }\n\n  /**\n   * Returns a string representing the method call to obtain the empty version of this Optional.\n   * This will be something like {@code \"Optional.empty()\"} or possibly {@code\n   * \"java.util.Optional.empty()\"}. It does not have a final semicolon.\n   *\n   * <p>This method is public so that it can be referenced as {@code p.optional.empty} from\n   * templates.\n   */\n  public String getEmpty() {\n    String empty = className.startsWith(\"java.util.\") ? \".empty()\" : \".absent()\";\n    return TypeEncoder.encodeRaw(optionalType) + empty;\n  }\n\n  TypeMirror getContainedType(Types typeUtils) {\n    List<? extends TypeMirror> typeArguments = optionalType.getTypeArguments();\n    switch (typeArguments.size()) {\n      case 1:\n        return typeArguments.get(0);\n      case 0:\n        return getContainedPrimitiveType(typeUtils);\n      default:\n        throw new AssertionError(\"Wrong number of type arguments: \" + optionalType);\n    }\n  }\n\n  String ofNullable() {\n    return className.equals(\"java.util.Optional\") ? \"ofNullable\" : \"fromNullable\";\n  }\n\n  private static final ImmutableMap<String, TypeKind> PRIMITIVE_TYPE_KINDS =\n      ImmutableMap.of(\n          \"OptionalDouble\", TypeKind.DOUBLE,\n          \"OptionalInt\", TypeKind.INT,\n          \"OptionalLong\", TypeKind.LONG);\n\n  private TypeMirror getContainedPrimitiveType(Types typeUtils) {\n    String simpleName = optionalType.asElement().getSimpleName().toString();\n    TypeKind typeKind = PRIMITIVE_TYPE_KINDS.get(simpleName);\n    Verify.verifyNotNull(typeKind, \"Could not get contained type of %s\", optionalType);\n    return typeUtils.getPrimitiveType(typeKind);\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/PropertyBuilderClassifier.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static java.util.stream.Collectors.collectingAndThen;\nimport static java.util.stream.Collectors.joining;\nimport static java.util.stream.Collectors.toMap;\n\nimport com.google.auto.common.MoreElements;\nimport com.google.auto.common.MoreTypes;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Optional;\nimport java.util.function.Function;\nimport java.util.function.Predicate;\nimport javax.lang.model.element.ElementKind;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.Modifier;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.ElementFilter;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.Types;\n\n/**\n * Classifies methods inside builder types that return builders for properties. For example, if\n * {@code @AutoValue} class Foo has a method {@code ImmutableList<String> bar()} then Foo.Builder\n * can have a method {@code ImmutableList.Builder<String> barBuilder()}. This class checks that a\n * method like {@code barBuilder()} follows the rules, and if so constructs a {@link\n * PropertyBuilder} instance with information about {@code barBuilder}.\n *\n * @author Éamonn McManus\n */\nclass PropertyBuilderClassifier {\n  private final ErrorReporter errorReporter;\n  private final Types typeUtils;\n  private final Elements elementUtils;\n  private final BuilderMethodClassifier<?> builderMethodClassifier;\n  private final Predicate<String> propertyIsNullable;\n  private final ImmutableMap<String, AnnotatedTypeMirror> propertyTypes;\n  private final Nullables nullables;\n\n  PropertyBuilderClassifier(\n      ErrorReporter errorReporter,\n      Types typeUtils,\n      Elements elementUtils,\n      BuilderMethodClassifier<?> builderMethodClassifier,\n      Predicate<String> propertyIsNullable,\n      ImmutableMap<String, AnnotatedTypeMirror> propertyTypes,\n      Nullables nullables) {\n    this.errorReporter = errorReporter;\n    this.typeUtils = typeUtils;\n    this.elementUtils = elementUtils;\n    this.builderMethodClassifier = builderMethodClassifier;\n    this.propertyIsNullable = propertyIsNullable;\n    this.propertyTypes = propertyTypes;\n    this.nullables = nullables;\n  }\n\n  /**\n   * Information about a property builder, referenced from the autovalue.vm template. A property\n   * called bar (defined by a method bar() or getBar()) can have a property builder called\n   * barBuilder(). For example, if {@code bar()} returns {@code ImmutableSet<String>} then {@code\n   * barBuilder()} might return {@code ImmutableSet.Builder<String>}.\n   */\n  public static class PropertyBuilder {\n    private final ExecutableElement propertyBuilderMethod;\n    private final String name;\n    private final String builderType;\n    private final String nullableBuilderType;\n    private final AnnotatedTypeMirror builderAnnotatedType;\n    private final String build;\n    private final String initializer;\n    private final String beforeInitDefault;\n    private final String initDefault;\n    private final String builtToBuilder;\n    private final String copyAll;\n\n    PropertyBuilder(\n        ExecutableElement propertyBuilderMethod,\n        String builderType,\n        String nullableBuilderType,\n        AnnotatedTypeMirror builderAnnotatedType,\n        String build,\n        String initializer,\n        String beforeInitDefault,\n        String initDefault,\n        String builtToBuilder,\n        String copyAll) {\n      this.propertyBuilderMethod = propertyBuilderMethod;\n      this.name = propertyBuilderMethod.getSimpleName() + \"$\";\n      this.builderType = builderType;\n      this.nullableBuilderType = nullableBuilderType;\n      this.builderAnnotatedType = builderAnnotatedType;\n      this.build = build;\n      this.initializer = initializer;\n      this.beforeInitDefault = beforeInitDefault;\n      this.initDefault = initDefault;\n      this.builtToBuilder = builtToBuilder;\n      this.copyAll = copyAll;\n    }\n\n    /** The property builder method, for example {@code barBuilder()}. */\n    public ExecutableElement getPropertyBuilderMethod() {\n      return propertyBuilderMethod;\n    }\n\n    /** The name of the property builder method. */\n    public String getMethodName() {\n      return propertyBuilderMethod.getSimpleName().toString();\n    }\n\n    /** The property builder method parameters, for example {@code Comparator<T> comparator} */\n    public String getPropertyBuilderMethodParameters() {\n      return propertyBuilderMethod.getParameters().stream()\n          .map(\n              parameter -> TypeEncoder.encode(parameter.asType()) + \" \" + parameter.getSimpleName())\n          .collect(joining(\", \"));\n    }\n\n    public String getAccess() {\n      return SimpleMethod.access(propertyBuilderMethod);\n    }\n\n    /** The name of the field to hold this builder. */\n    public String getName() {\n      return name;\n    }\n\n    /** The type of the builder, for example {@code ImmutableSet.Builder<String>}. */\n    public String getBuilderType() {\n      return builderType;\n    }\n\n    /** The type of the builder with an appropriate {@code @Nullable} type annotation. */\n    public String getNullableBuilderType() {\n      return nullableBuilderType;\n    }\n\n    TypeMirror getBuilderTypeMirror() {\n      return builderAnnotatedType.getType();\n    }\n\n    /** The name of the build method, {@code build} or {@code buildOrThrow}. */\n    public String getBuild() {\n      return build;\n    }\n\n    /** An initializer for the builder field, for example {@code ImmutableSet.builder()}. */\n    public String getInitializer() {\n      return initializer;\n    }\n\n    /**\n     * An empty string, or a complete statement to be included before the expression returned by\n     * {@link #getInitDefault()}.\n     */\n    public String getBeforeInitDefault() {\n      return beforeInitDefault;\n    }\n\n    /**\n     * An expression to return a default instance of the type that this builder builds. For example,\n     * if this is an {@code ImmutableList<String>} then the method {@code ImmutableList.of()} will\n     * correctly return an empty {@code ImmutableList<String>}, assuming the appropriate context for\n     * type inference. The expression here can assume that the statement from {@link\n     * #getBeforeInitDefault} has preceded it.\n     */\n    public String getInitDefault() {\n      return initDefault;\n    }\n\n    /**\n     * A method to convert the built type back into a builder. Unfortunately Guava collections don't\n     * have this (you can't say {@code myImmutableMap.toBuilder()}), but for other types such as\n     * {@code @AutoValue} types this is {@code toBuilder()}.\n     */\n    public String getBuiltToBuilder() {\n      return builtToBuilder;\n    }\n\n    /**\n     * The method to copy another collection into this builder. It is {@code addAll} for\n     * one-dimensional collections like {@code ImmutableList} and {@code ImmutableSet}, and it is\n     * {@code putAll} for two-dimensional collections like {@code ImmutableMap} and {@code\n     * ImmutableTable}.\n     */\n    public String getCopyAll() {\n      return copyAll;\n    }\n  }\n\n  // Our @AutoValue class `Foo` has a property `Bar bar()` or `Bar getBar()` and we've encountered\n  // a builder method like `BarBuilder barBuilder()`. Here `BarBuilder` can have any name (its name\n  // doesn't have to be the name of `Bar` with `Builder` stuck on the end), but `barBuilder()` does\n  // have to be the name of the property with `Builder` stuck on the end. The requirements for the\n  // `BarBuilder` type are:\n  // (1) It must have an instance method called `build()` or `buildOrThrow() that returns `Bar`. If\n  //      the type of `bar()` is `Bar<String>` then the type of the build method must be\n  //      `Bar<String>`.\n  // (2) `BarBuilder` must have a public no-arg constructor, or `Bar` must have a static method\n  //     `naturalOrder(), `builder()`, or `newBuilder()` that returns `BarBuilder`. The\n  //     `naturalOrder()` case is specifically for ImmutableSortedSet and ImmutableSortedMap.\n  // (3) If `Foo` has a `toBuilder()` method, or if we have both `barBuilder()` and `setBar(Bar)`\n  //     methods, then `Bar` must have an instance method `BarBuilder toBuilder()`, or `BarBuilder`\n  //     must have an `addAll` or `putAll` method that accepts an argument of type `Bar`.\n  //\n  // This method outputs an error and returns Optional.empty() if the barBuilder() method has a\n  // problem.\n  Optional<PropertyBuilder> makePropertyBuilder(ExecutableElement method, String property) {\n    AnnotatedTypeMirror barBuilderAnnotatedType =\n        builderMethodClassifier.builderMethodReturnType(method);\n    if (barBuilderAnnotatedType.getKind() != TypeKind.DECLARED) {\n      errorReporter.reportError(\n          method,\n          \"[AutoValueOddBuilderMethod] Method looks like a property builder, but its return type\"\n              + \" is not a class or interface\");\n      return Optional.empty();\n    }\n    DeclaredType barBuilderDeclaredType = MoreTypes.asDeclared(barBuilderAnnotatedType.getType());\n    TypeElement barBuilderTypeElement = MoreTypes.asTypeElement(barBuilderDeclaredType);\n    Map<String, ExecutableElement> barBuilderNoArgMethods = noArgMethodsOf(barBuilderTypeElement);\n\n    TypeMirror barTypeMirror = propertyTypes.get(property).getType();\n    if (barTypeMirror.getKind() != TypeKind.DECLARED) {\n      errorReporter.reportError(\n          method,\n          \"[AutoValueBadBuilderMethod] Method looks like a property builder, but the type of\"\n              + \" property %s is not a class or interface\",\n          property);\n      return Optional.empty();\n    }\n    if (propertyIsNullable.test(property)) {\n      errorReporter.reportError(\n          method,\n          \"[AutoValueNullBuilder] Property %s is @Nullable so it cannot have a property builder\",\n          property);\n    }\n    TypeElement barTypeElement = MoreTypes.asTypeElement(barTypeMirror);\n    Map<String, ExecutableElement> barNoArgMethods = noArgMethodsOf(barTypeElement);\n\n    // Condition (1), must have build() or buildOrThrow() method returning Bar.\n    ExecutableElement build = barBuilderNoArgMethods.get(\"buildOrThrow\");\n    if (build == null) {\n      build = barBuilderNoArgMethods.get(\"build\");\n    }\n    if (build == null || build.getModifiers().contains(Modifier.STATIC)) {\n      errorReporter.reportError(\n          method,\n          \"[AutoValueBuilderNotBuildable] Method looks like a property builder, but it returns %s\"\n              + \" which does not have a non-static build() or buildOrThrow() method\",\n          barBuilderTypeElement);\n      return Optional.empty();\n    }\n\n    // We've determined that `BarBuilder` has a method `build()` or `buildOrThrow(). But it must\n    // return `Bar`. And if the type of `bar()` is Bar<String> then `BarBuilder.build()` must return\n    // something that can be assigned to Bar<String>.\n    TypeMirror buildType =\n        MethodSignature.asMemberOf(typeUtils, barBuilderDeclaredType, build).returnType().getType();\n    if (!typeUtils.isAssignable(buildType, barTypeMirror)) {\n      errorReporter.reportError(\n          method,\n          \"[AutoValueBuilderWrongType] Property builder for %s has type %s whose %s() method\"\n              + \" returns %s instead of %s\",\n          property,\n          barBuilderTypeElement,\n          build.getSimpleName(),\n          buildType,\n          barTypeMirror);\n      return Optional.empty();\n    }\n\n    Optional<ExecutableElement> maybeBuilderMaker;\n    if (method.getParameters().isEmpty()) {\n      maybeBuilderMaker = noArgBuilderMaker(barNoArgMethods, barBuilderTypeElement);\n    } else {\n      Map<String, ExecutableElement> barOneArgMethods = oneArgumentMethodsOf(barTypeElement);\n      maybeBuilderMaker = oneArgBuilderMaker(barOneArgMethods, barBuilderTypeElement);\n    }\n    if (!maybeBuilderMaker.isPresent()) {\n      errorReporter.reportError(\n          method,\n          \"[AutoValueCantMakePropertyBuilder] Method looks like a property builder, but its type\"\n              + \" %s does not have a public constructor and %s does not have a static builder() or\"\n              + \" newBuilder() method that returns %s\",\n          barBuilderTypeElement,\n          barTypeElement,\n          barBuilderTypeElement);\n      return Optional.empty();\n    }\n    ExecutableElement builderMaker = maybeBuilderMaker.get();\n\n    String barBuilderType = TypeEncoder.encodeWithAnnotations(barBuilderAnnotatedType);\n    String nullableBarBuilderType =\n        TypeEncoder.encodeWithAnnotations(\n            barBuilderAnnotatedType, nullables.nullableTypeAnnotations());\n    String rawBarType = TypeEncoder.encodeRaw(barTypeMirror);\n    String arguments =\n        method.getParameters().isEmpty()\n            ? \"()\"\n            : \"(\" + method.getParameters().get(0).getSimpleName() + \")\";\n    String initializer =\n        (builderMaker.getKind() == ElementKind.CONSTRUCTOR)\n            ? \"new \" + barBuilderType + arguments\n            : rawBarType + \".\" + builderMaker.getSimpleName() + arguments;\n    String builtToBuilder = null;\n    String copyAll = null;\n    ExecutableElement toBuilder = barNoArgMethods.get(\"toBuilder\");\n    if (toBuilder != null\n        && !toBuilder.getModifiers().contains(Modifier.STATIC)\n        && typeUtils.isAssignable(\n            typeUtils.erasure(toBuilder.getReturnType()),\n            typeUtils.erasure(barBuilderDeclaredType))) {\n      builtToBuilder = toBuilder.getSimpleName().toString();\n    } else {\n      Optional<ExecutableElement> maybeCopyAll =\n          addAllPutAll(barBuilderTypeElement, barBuilderDeclaredType, barTypeMirror);\n      if (maybeCopyAll.isPresent()) {\n        copyAll = maybeCopyAll.get().getSimpleName().toString();\n      }\n    }\n    ExecutableElement barOf = barNoArgMethods.get(\"of\");\n    boolean hasOf = (barOf != null && barOf.getModifiers().contains(Modifier.STATIC));\n    // An expression (initDefault) to make a default one of these, plus optionally a statement\n    // (beforeInitDefault) that prepares the expression. For a collection, beforeInitDefault is\n    // empty and initDefault is (e.g.) `ImmutableList.of()`. For a nested value type,\n    // beforeInitDefault is (e.g.)\n    //   `NestedAutoValueType.Builder foo$builder = NestedAutoValueType.builder();`\n    // and initDefault is `foo$builder.build();`. The reason for the separate statement is to\n    // exploit type inference rather than having to write `NestedAutoValueType.<Bar>build();`.\n    String beforeInitDefault;\n    String initDefault;\n    if (hasOf) {\n      beforeInitDefault = \"\";\n      initDefault = rawBarType + \".of()\";\n    } else {\n      String localBuilder = property + \"$builder\";\n      beforeInitDefault = nullableBarBuilderType + \" \" + localBuilder + \" = \" + initializer + \";\";\n      initDefault = localBuilder + \".\" + build.getSimpleName() + \"()\";\n    }\n\n    PropertyBuilder propertyBuilder =\n        new PropertyBuilder(\n            method,\n            barBuilderType,\n            nullableBarBuilderType,\n            barBuilderAnnotatedType,\n            build.getSimpleName().toString(),\n            initializer,\n            beforeInitDefault,\n            initDefault,\n            builtToBuilder,\n            copyAll);\n    return Optional.of(propertyBuilder);\n  }\n\n  private static final ImmutableSet<String> BUILDER_METHOD_NAMES =\n      ImmutableSet.of(\"naturalOrder\", \"builder\", \"newBuilder\");\n\n  // (2) `BarBuilder` must have a public no-arg constructor, or `Bar` must have a visible static\n  //      method `naturalOrder(), `builder()`, or `newBuilder()` that returns `BarBuilder`; or,\n  //      if we have a foosBuilder(T) method, then `BarBuilder` must have a public constructor with\n  //      a single parameter assignable from T, or a visible static `builder(T)` method.\n  private Optional<ExecutableElement> noArgBuilderMaker(\n      Map<String, ExecutableElement> barNoArgMethods, TypeElement barBuilderTypeElement) {\n    return builderMaker(BUILDER_METHOD_NAMES, barNoArgMethods, barBuilderTypeElement, 0);\n  }\n\n  private static final ImmutableSet<String> ONE_ARGUMENT_BUILDER_METHOD_NAMES =\n      ImmutableSet.of(\"builder\");\n\n  private Optional<ExecutableElement> oneArgBuilderMaker(\n      Map<String, ExecutableElement> barOneArgMethods, TypeElement barBuilderTypeElement) {\n\n    return builderMaker(\n        ONE_ARGUMENT_BUILDER_METHOD_NAMES, barOneArgMethods, barBuilderTypeElement, 1);\n  }\n\n  private Optional<ExecutableElement> builderMaker(\n      ImmutableSet<String> methodNamesToCheck,\n      Map<String, ExecutableElement> methods,\n      TypeElement barBuilderTypeElement,\n      int argumentCount) {\n    Optional<ExecutableElement> maybeMethod =\n        methodNamesToCheck.stream()\n            .map(methods::get)\n            .filter(Objects::nonNull)\n            .filter(method -> method.getModifiers().contains(Modifier.STATIC))\n            .filter(\n                method ->\n                    typeUtils.isSameType(\n                        typeUtils.erasure(method.getReturnType()),\n                        typeUtils.erasure(barBuilderTypeElement.asType())))\n            .findFirst();\n\n    if (maybeMethod.isPresent()) {\n      // TODO(emcmanus): check visibility. We don't want to require public for @AutoValue\n      // builders. By not checking visibility we risk accepting something as a builder maker\n      // and then failing when the generated code tries to call Bar.builder(). But the risk\n      // seems small.\n      return maybeMethod;\n    }\n\n    return ElementFilter.constructorsIn(barBuilderTypeElement.getEnclosedElements()).stream()\n        .filter(c -> c.getParameters().size() == argumentCount)\n        .filter(c -> c.getModifiers().contains(Modifier.PUBLIC))\n        .findFirst();\n  }\n\n  private Map<String, ExecutableElement> noArgMethodsOf(TypeElement type) {\n    return methodsOf(type, 0);\n  }\n\n  private ImmutableMap<String, ExecutableElement> oneArgumentMethodsOf(TypeElement type) {\n    return methodsOf(type, 1);\n  }\n\n  private ImmutableMap<String, ExecutableElement> methodsOf(TypeElement type, int argumentCount) {\n    return ElementFilter.methodsIn(elementUtils.getAllMembers(type)).stream()\n        .filter(method -> method.getParameters().size() == argumentCount)\n        .filter(method -> !isStaticInterfaceMethodNotIn(method, type))\n        .collect(\n            collectingAndThen(\n                toMap(\n                    method -> method.getSimpleName().toString(),\n                    Function.identity(),\n                    (method1, method2) -> method1),\n                ImmutableMap::copyOf));\n  }\n\n  // Work around an Eclipse compiler bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=547185\n  // The result of Elements.getAllMembers includes static methods declared in superinterfaces.\n  // That's wrong because those aren't inherited. So this method checks whether the given method is\n  // a static interface method not in the given type.\n  private static boolean isStaticInterfaceMethodNotIn(ExecutableElement method, TypeElement type) {\n    return method.getModifiers().contains(Modifier.STATIC)\n        && !method.getEnclosingElement().equals(type)\n        && method.getEnclosingElement().getKind().equals(ElementKind.INTERFACE);\n  }\n\n  private static final ImmutableSet<String> ADD_ALL_PUT_ALL = ImmutableSet.of(\"addAll\", \"putAll\");\n\n  // We have `Bar bar()` and `Foo.Builder toBuilder()` in the @AutoValue type Foo, and we have\n  // `BarBuilder barBuilder()` in Foo.Builder. That means that we need to be able to make a\n  // `BarBuilder` from a `Bar` as part of the implementation of `Foo.toBuilder()`. We can do that\n  // if `Bar` has a method `BarBuilder toBuilder()`, but what if it doesn't? For example, Guava's\n  // `ImmutableList` doesn't have a method `ImmutableList.Builder toBuilder()`. So we also allow it\n  // to work if `BarBuilder` has a method `addAll(T)` or `putAll(T)`, where `Bar` is assignable to\n  // `T`. `ImmutableList.Builder<E>` does have a method `addAll(Iterable<? extends E>)` and\n  // `ImmutableList<E>` is assignable to `Iterable<? extends E>`, so that works.\n  private Optional<ExecutableElement> addAllPutAll(\n      TypeElement barBuilderTypeElement,\n      DeclaredType barBuilderDeclaredType,\n      TypeMirror barTypeMirror) {\n    return MoreElements.getLocalAndInheritedMethods(barBuilderTypeElement, typeUtils, elementUtils)\n        .stream()\n        .filter(\n            method ->\n                ADD_ALL_PUT_ALL.contains(method.getSimpleName().toString())\n                    && method.getParameters().size() == 1)\n        .filter(\n            method -> {\n              TypeMirror parameterType =\n                  MethodSignature.asMemberOf(typeUtils, barBuilderDeclaredType, method)\n                      .parameterTypes()\n                      .get(0)\n                      .getType();\n              return typeUtils.isAssignable(barTypeMirror, parameterType);\n            })\n        .findFirst();\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/PropertyNames.java",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport com.google.common.base.Strings;\n\n/** Helper methods to create property names. */\nclass PropertyNames {\n  /**\n   * Returns the {@code propertyName} with its first character in lower case, but leaves it intact\n   * if it starts with two capitals.\n   *\n   * <p>For consistency with JavaBeans, a getter called {@code getHTMLPage()} defines a property\n   * called {@code HTMLPage}. The <a\n   * href=\"https://docs.oracle.com/javase/8/docs/api/java/beans/Introspector.html#decapitalize-java.lang.String-\">\n   * rule</a> is: the name of the property is the part after {@code get} or {@code is}, with the\n   * first letter lowercased <i>unless</i> the first two letters are uppercase. This works well for\n   * the {@code HTMLPage} example, but in these more enlightened times we use {@code HtmlPage}\n   * anyway, so the special behaviour is not useful, and of course it behaves poorly with examples\n   * like {@code OAuth}. Nevertheless, we preserve it for compatibility.\n   */\n  static String decapitalizeLikeJavaBeans(String propertyName) {\n    if (propertyName != null\n        && propertyName.length() >= 2\n        && Character.isUpperCase(propertyName.charAt(0))\n        && Character.isUpperCase(propertyName.charAt(1))) {\n      return propertyName;\n    }\n    return decapitalizeNormally(propertyName);\n  }\n\n  /** Returns the {@code propertyName} with its first character in lower case. */\n  static String decapitalizeNormally(String propertyName) {\n    if (Strings.isNullOrEmpty(propertyName)) {\n      return propertyName;\n    }\n    return Character.toLowerCase(propertyName.charAt(0)) + propertyName.substring(1);\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/Reformatter.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport com.google.common.base.CharMatcher;\n\n/**\n * Postprocessor that runs over the output of the template engine in order to make it look nicer.\n * Mostly, this involves removing surplus horizontal and vertical space.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\nclass Reformatter {\n  /**\n   * Characters that might start a continuation line. Since Google Style requires splitting before\n   * operators, we expect that a continuation line will begin with one of these (or be inside\n   * parentheses). We've omitted {@code /} from this list for now since none of our templates splits\n   * before one, and otherwise we'd have to handle {@code //} and {@code /*}.\n   */\n  private static final CharMatcher OPERATORS = CharMatcher.anyOf(\"+-*%&|^<>=?:.\").precomputed();\n\n  static String fixup(String s) {\n    StringBuilder out = new StringBuilder();\n    JavaScanner scanner = new JavaScanner(s);\n    s = scanner.string();\n    int len = s.length();\n    for (int start = 0, previous = 0, braces = 0, parens = 0, end = 0;\n        start < len;\n        previous = start, start = end) {\n      end = scanner.tokenEnd(start);\n      // The tokenized string always ends with \\n so we can usually look at s.charAt(end) without\n      // worrying about going past the end of the string.\n      switch (s.charAt(start)) {\n        case '(':\n          parens++;\n          break;\n        case ')':\n          parens--;\n          break;\n        case '{':\n          braces++;\n          break;\n        case '}':\n          braces--;\n          break;\n        case ' ':\n          // This token is a string of consecutive spaces that is not at the start of a line.\n          // Consecutive spaces at the start of a line are attached to the previous newline, and\n          // we delete spaces at the start of the first line. So we are going to compress this\n          // into just one space, and we are going to delete it entirely if it follows '(' or\n          // precedes a newline or one of the punctuation characters here.\n          if (start > 0 && s.charAt(previous) != '(' && \"\\n.,;)\".indexOf(s.charAt(end)) < 0) {\n            out.append(' ');\n          }\n          continue;\n        case '\\n':\n          // This token is a newline plus any following spaces (the indentation of the next line).\n          // If it is followed by something other than a newline then we will output the\n          // newline, and replace the following spaces by our computed indentation. Otherwise, the\n          // token is part of a sequence of newlines but it is not the last one. If this is a\n          // context where we delete blank lines, or if this is not the first new line in the\n          // sequence, or if we are at the start of the file, we will delete this one. Otherwise we\n          // will output a single newline with no following indentation. Contexts where we delete\n          // blank lines are inside parentheses or inside more than one set of braces.\n          if (end < len && s.charAt(end) != '\\n') {\n            // Omit newlines at the very start of the file. Also delete newline+indent between\n            // ( and ), since that shows up in some places where we output one parameter per line,\n            // when there are no parameters.\n            char prev = s.charAt(previous);\n            char next = s.charAt(end);\n            if (out.length() > 0 && (prev != '(' || next != ')')) {\n              out.append('\\n');\n              // Replace any space after the newline with our computed indentation. The algorithm\n              // here is simplistic but works OK for our current templates.\n              int indent = braces * 2;\n              if (parens > 0 || OPERATORS.matches(next)) {\n                indent += 4;\n              } else if (next == '}') {\n                indent -= 2;\n              }\n              for (int i = 0; i < indent; i++) {\n                out.append(' ');\n              }\n            }\n            continue;\n          }\n          if (parens == 0 && braces < 2 && s.charAt(previous) != '\\n' && out.length() > 0) {\n            out.append('\\n');\n          }\n          continue;\n        default:\n          break;\n      }\n      out.append(s, start, end);\n    }\n    return out.toString();\n  }\n\n  private Reformatter() {}\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/SimpleMethod.java",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static java.util.stream.Collectors.joining;\n\nimport java.util.Set;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.Modifier;\n\n/**\n * A method on an {@code @AutoValue} or {@code AutoOneOf} class that has no specific attached\n * information, such as a {@code toBuilder()} method, or a {@code build()} method, where only the\n * name and access type is needed in context.\n *\n * <p>It implements JavaBean-style getters which means it can be referenced from templates, for\n * example {@code $method.access}. This template access means that the class and its getters must be\n * public.\n */\npublic final class SimpleMethod {\n  private final String access;\n  private final String name;\n  private final String throwsString;\n\n  SimpleMethod(ExecutableElement method) {\n    this.access = access(method);\n    this.name = method.getSimpleName().toString();\n    this.throwsString = throwsString(method);\n  }\n\n  public String getAccess() {\n    return access;\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public String getThrows() {\n    return throwsString;\n  }\n\n  /**\n   * Returns an appropriate string to be used in code for the access specification of the given\n   * method. This will be {@code public} or {@code protected} followed by a space, or the empty\n   * string for default access.\n   */\n  static String access(ExecutableElement method) {\n    Set<Modifier> mods = method.getModifiers();\n    if (mods.contains(Modifier.PUBLIC)) {\n      return \"public \";\n    } else if (mods.contains(Modifier.PROTECTED)) {\n      return \"protected \";\n    } else {\n      return \"\";\n    }\n  }\n\n  private static String throwsString(ExecutableElement method) {\n    if (method.getThrownTypes().isEmpty()) {\n      return \"\";\n    }\n    return \"throws \"\n        + method.getThrownTypes().stream().map(TypeEncoder::encode).collect(joining(\", \"));\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/SimpleServiceLoader.java",
    "content": "/*\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static java.nio.charset.StandardCharsets.UTF_8;\nimport static java.util.stream.Collectors.toList;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Streams;\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.net.URL;\nimport java.net.URLConnection;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Optional;\nimport java.util.ServiceConfigurationError;\nimport java.util.regex.Pattern;\n\n/**\n * A replacement for {@link java.util.ServiceLoader} that avoids certain long-standing bugs. This\n * simpler implementation does not bother with lazy loading but returns all the service\n * implementations in one list. It makes sure that {@link URLConnection#setUseCaches} is called to\n * turn off jar caching, since that tends to lead to problems in versions before JDK 9.\n *\n * @see <a href=\"https://github.com/google/auto/issues/718\">Issue #718</a>\n * @see <a href=\"https://bugs.openjdk.java.net/browse/JDK-8156014\">JDK-8156014</a>\n */\npublic final class SimpleServiceLoader {\n  private SimpleServiceLoader() {}\n\n  public static <T> ImmutableList<T> load(Class<? extends T> service, ClassLoader loader) {\n    return load(service, loader, Optional.empty());\n  }\n\n  public static <T> ImmutableList<T> load(\n      Class<? extends T> service, ClassLoader loader, Optional<Pattern> allowedMissingClasses) {\n    String resourceName = \"META-INF/services/\" + service.getName();\n    List<URL> resourceUrls;\n    try {\n      resourceUrls = Collections.list(loader.getResources(resourceName));\n    } catch (IOException e) {\n      throw new ServiceConfigurationError(\"Could not look up \" + resourceName, e);\n    }\n    ImmutableSet.Builder<Class<? extends T>> providerClasses = ImmutableSet.builder();\n    for (URL resourceUrl : resourceUrls) {\n      try {\n        providerClasses.addAll(\n            providerClassesFromUrl(resourceUrl, service, loader, allowedMissingClasses));\n      } catch (IOException e) {\n        throw new ServiceConfigurationError(\"Could not read \" + resourceUrl, e);\n      }\n    }\n    ImmutableList.Builder<T> providers = ImmutableList.builder();\n    for (Class<? extends T> providerClass : providerClasses.build()) {\n      try {\n        T provider = providerClass.getConstructor().newInstance();\n        providers.add(provider);\n      } catch (ReflectiveOperationException e) {\n        throw new ServiceConfigurationError(\"Could not construct \" + providerClass.getName(), e);\n      }\n    }\n    return providers.build();\n  }\n\n  private static <T> ImmutableSet<Class<? extends T>> providerClassesFromUrl(\n      URL resourceUrl,\n      Class<? extends T> service,\n      ClassLoader loader,\n      Optional<Pattern> allowedMissingClasses)\n      throws IOException {\n    ImmutableSet.Builder<Class<? extends T>> providerClasses = ImmutableSet.builder();\n    URLConnection urlConnection = resourceUrl.openConnection();\n    urlConnection.setUseCaches(false);\n    List<String> lines;\n    try (InputStream in = urlConnection.getInputStream();\n        BufferedReader reader = new BufferedReader(new InputStreamReader(in, UTF_8))) {\n      lines = reader.lines().collect(toList());\n    }\n    List<String> classNames =\n        lines.stream()\n            .map(SimpleServiceLoader::parseClassName)\n            .flatMap(Streams::stream)\n            .collect(toList());\n    for (String className : classNames) {\n      Class<?> c;\n      try {\n        c = Class.forName(className, false, loader);\n      } catch (ClassNotFoundException e) {\n        if (allowedMissingClasses.isPresent()\n            && allowedMissingClasses.get().matcher(className).matches()) {\n          continue;\n        }\n        throw new ServiceConfigurationError(\"Could not load \" + className, e);\n      }\n      if (!service.isAssignableFrom(c)) {\n        throw new ServiceConfigurationError(\n            \"Class \" + className + \" is not assignable to \" + service.getName());\n      }\n      providerClasses.add(c.asSubclass(service));\n    }\n    return providerClasses.build();\n  }\n\n  private static Optional<String> parseClassName(String line) {\n    int hash = line.indexOf('#');\n    if (hash >= 0) {\n      line = line.substring(0, hash);\n    }\n    line = line.trim();\n    return line.isEmpty() ? Optional.empty() : Optional.of(line);\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/TemplateVars.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static java.nio.charset.StandardCharsets.UTF_8;\n\nimport com.google.common.base.Ascii;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.io.ByteStreams;\nimport com.google.escapevelocity.Template;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.io.Reader;\nimport java.io.StringReader;\nimport java.io.UncheckedIOException;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Modifier;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.net.URL;\nimport java.util.Map;\nimport java.util.TreeMap;\nimport java.util.jar.JarFile;\n\n/**\n * A template and a set of variables to be substituted into that template. A concrete subclass of\n * this class defines a set of fields that are template variables, and an implementation of the\n * {@link #parsedTemplate()} method which is the template to substitute them into. Once the values\n * of the fields have been assigned, the {@link #toText()} method returns the result of substituting\n * them into the template.\n *\n * <p>The subclass may be a direct subclass of this class or a more distant descendant. Every field\n * in the starting class and its ancestors up to this class will be included. Fields cannot be\n * static unless they are also final. They cannot be private, though they can be package-private if\n * the class is in the same package as this class. They cannot be primitive or null, so that there\n * is a clear indication when a field has not been set.\n *\n * @author Éamonn McManus\n */\nabstract class TemplateVars {\n  abstract Template parsedTemplate();\n\n  private final ImmutableList<Field> fields;\n\n  TemplateVars() {\n    this.fields = getFields(getClass());\n  }\n\n  private static ImmutableList<Field> getFields(Class<?> c) {\n    ImmutableList.Builder<Field> fieldsBuilder = ImmutableList.builder();\n    while (c != TemplateVars.class) {\n      addFields(fieldsBuilder, c.getDeclaredFields());\n      c = c.getSuperclass();\n    }\n    return fieldsBuilder.build();\n  }\n\n  private static void addFields(\n      ImmutableList.Builder<Field> fieldsBuilder, Field[] declaredFields) {\n    for (Field field : declaredFields) {\n      if (field.isSynthetic() || isStaticFinal(field)) {\n        continue;\n      }\n      if (Modifier.isPrivate(field.getModifiers())) {\n        throw new IllegalArgumentException(\"Field cannot be private: \" + field);\n      }\n      if (Modifier.isStatic(field.getModifiers())) {\n        throw new IllegalArgumentException(\"Field cannot be static unless also final: \" + field);\n      }\n      if (field.getType().isPrimitive()) {\n        throw new IllegalArgumentException(\"Field cannot be primitive: \" + field);\n      }\n      fieldsBuilder.add(field);\n    }\n  }\n\n  /**\n   * Returns the result of substituting the variables defined by the fields of this class (a\n   * concrete subclass of TemplateVars) into the template returned by {@link #parsedTemplate()}.\n   */\n  String toText() {\n    ImmutableMap<String, Object> vars = toVars();\n    return parsedTemplate().evaluate(vars);\n  }\n\n  private ImmutableMap<String, Object> toVars() {\n    Map<String, Object> vars = new TreeMap<>();\n    for (Field field : fields) {\n      Object value = fieldValue(field, this);\n      if (value == null) {\n        throw new IllegalArgumentException(\"Field cannot be null (was it set?): \" + field);\n      }\n      Object old = vars.put(field.getName(), value);\n      if (old != null) {\n        throw new IllegalArgumentException(\"Two fields called \" + field.getName() + \"?!\");\n      }\n    }\n    return ImmutableMap.copyOf(vars);\n  }\n\n  @Override\n  public String toString() {\n    return getClass().getSimpleName() + toVars();\n  }\n\n  static Template parsedTemplateForResource(String resourceName) {\n    try {\n      return Template.parseFrom(resourceName, TemplateVars::readerFromUrl);\n    } catch (IOException e) {\n      throw new UncheckedIOException(e);\n    }\n  }\n\n  // This is an ugly workaround for https://bugs.openjdk.java.net/browse/JDK-6947916, as\n  // reported in https://github.com/google/auto/issues/365.\n  // The issue is that sometimes the InputStream returned by JarURLCollection.getInputStream()\n  // can be closed prematurely, which leads to an IOException saying \"Stream closed\".\n  // To avoid that issue, we open the jar file directly and load the resource from it. Since that\n  // doesn't use JarURLConnection, it shouldn't be susceptible to the same bug.\n  private static Reader readerFromUrl(String resourceName) throws IOException {\n    URL resourceUrl = TemplateVars.class.getResource(resourceName);\n    if (resourceUrl == null) {\n      throw new IllegalArgumentException(\"Could not find resource: \" + resourceName);\n    }\n    try {\n      if (Ascii.equalsIgnoreCase(resourceUrl.getProtocol(), \"file\")) {\n        return readerFromFile(resourceUrl);\n      } else if (Ascii.equalsIgnoreCase(resourceUrl.getProtocol(), \"jar\")) {\n        return readerFromJar(resourceUrl);\n      } else {\n        return readerFromOther(resourceUrl);\n      }\n    } catch (URISyntaxException e) {\n      throw new IOException(e);\n    }\n  }\n\n  private static Reader readerFromJar(URL resourceUrl) throws URISyntaxException, IOException {\n    // Jar URLs look like this: jar:file:/path/to/file.jar!/entry/within/jar\n    // So take apart the URL to open the jar /path/to/file.jar and read the entry\n    // entry/within/jar from it.\n    // We could use the methods from JarURLConnection here, but that would risk provoking the same\n    // problem that prompted this workaround in the first place.\n    String resourceUrlString = resourceUrl.toString().substring(\"jar:\".length());\n    int bang = resourceUrlString.lastIndexOf('!');\n    String entryName = resourceUrlString.substring(bang + 1);\n    if (entryName.startsWith(\"/\")) {\n      entryName = entryName.substring(1);\n    }\n    URI jarUri = new URI(resourceUrlString.substring(0, bang));\n    try (JarFile jar = new JarFile(new File(jarUri));\n        InputStream in = jar.getInputStream(jar.getJarEntry(entryName))) {\n      String contents = new String(ByteStreams.toByteArray(in), UTF_8);\n      return new StringReader(contents);\n    }\n  }\n\n  // In most execution environments, we'll be dealing with a jar, but we handle individual files\n  // just for cases like running our tests with Maven.\n  private static Reader readerFromFile(URL resourceUrl) throws IOException, URISyntaxException {\n    File resourceFile = new File(resourceUrl.toURI());\n    return new InputStreamReader(new FileInputStream(resourceFile), UTF_8);\n  }\n\n  // As a fallback, we handle other kinds of URL naively. For example, if we're executing in GraalVM\n  // code, we might have a `resource:` URL. This code is not currently covered by unit tests.\n  // See https://github.com/google/auto/issues/1783.\n  private static Reader readerFromOther(URL resourceUrl) throws IOException {\n    return new InputStreamReader(resourceUrl.openStream(), UTF_8);\n  }\n\n  private static Object fieldValue(Field field, Object container) {\n    try {\n      return field.get(container);\n    } catch (IllegalAccessException e) {\n      throw new RuntimeException(e);\n    }\n  }\n\n  private static boolean isStaticFinal(Field field) {\n    int modifiers = field.getModifiers();\n    return Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers);\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/TypeEncoder.java",
    "content": "/*\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.base.Preconditions.checkArgument;\nimport static com.google.common.base.Preconditions.checkState;\nimport static java.util.stream.Collectors.toList;\n\nimport com.google.auto.common.MoreElements;\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.value.processor.MissingTypes.MissingTypeException;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport java.util.List;\nimport java.util.OptionalInt;\nimport java.util.Set;\nimport java.util.function.Function;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.TypeParameterElement;\nimport javax.lang.model.type.ArrayType;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.ErrorType;\nimport javax.lang.model.type.PrimitiveType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.type.TypeVariable;\nimport javax.lang.model.type.WildcardType;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.SimpleTypeVisitor8;\nimport javax.lang.model.util.Types;\n\n/**\n * Encodes types so they can later be decoded to incorporate imports.\n *\n * <p>The idea is that types that appear in generated source code use {@link #encode}, which will\n * spell out a type like {@code java.util.List<? extends java.lang.Number>}, except that wherever a\n * class name appears it is replaced by a special token. So the spelling might actually be {@code\n * `java.util.List`<? extends `java.lang.Number`>}. Then once the entire class has been generated,\n * {@code #decode} scans for these tokens to determine what classes need to be imported, and\n * replaces the tokens with the correct spelling given the imports. So here, {@code java.util.List}\n * would be imported, and the final spelling would be {@code List<? extends Number>} (knowing that\n * {@code Number} is implicitly imported). The special token {@code `import`} marks where the\n * imports should be, and {@link #decode} replaces it with the correct list of imports.\n *\n * <p>The funky syntax for type annotations on qualified type names requires an adjustment to this\n * scheme. {@code `«java.util.Map`} stands for {@code java.util.} and {@code `»java.util.Map`}\n * stands for {@code Map}. If {@code java.util.Map} is imported, then {@code `«java.util.Map`} will\n * eventually be empty, but if {@code java.util.Map} is not imported (perhaps because there is\n * another {@code Map} in scope) then {@code `«java.util.Map`} will be {@code java.util.}. The end\n * result is that the code can contain {@code `«java.util.Map`@`javax.annotation.Nullable`\n * `»java.util.Map`}. That might decode to {@code @Nullable Map} or to {@code java.util.@Nullable\n * Map} or even to {@code java.util.@javax.annotation.Nullable Map}.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\nfinal class TypeEncoder {\n  private TypeEncoder() {} // There are no instances of this class.\n\n  private static final EncodingTypeVisitor ENCODING_TYPE_VISITOR = new EncodingTypeVisitor();\n  private static final RawEncodingTypeVisitor RAW_ENCODING_TYPE_VISITOR =\n      new RawEncodingTypeVisitor();\n\n  /**\n   * Returns the encoding for the given type, where class names are marked by special tokens. The\n   * encoding for {@code int} will be {@code int}, but the encoding for {@code\n   * java.util.List<java.lang.Integer>} will be {@code `java.util.List`<`java.lang.Integer`>}.\n   */\n  static String encode(TypeMirror type) {\n    StringBuilder sb = new StringBuilder();\n    return type.accept(ENCODING_TYPE_VISITOR, sb).toString();\n  }\n\n  /**\n   * Like {@link #encode}, except that only the raw type is encoded. So if the given type is {@code\n   * java.util.List<java.lang.Integer>} the result will be {@code `java.util.List`}.\n   */\n  static String encodeRaw(TypeMirror type) {\n    StringBuilder sb = new StringBuilder();\n    return type.accept(RAW_ENCODING_TYPE_VISITOR, sb).toString();\n  }\n\n  /**\n   * Encodes the given type and its type annotations. The class comment for {@link TypeEncoder}\n   * covers the details of annotation encoding.\n   */\n  static String encodeWithAnnotations(TypeMirror type) {\n    return encodeWithAnnotations(type, ImmutableList.of(), ImmutableSet.of());\n  }\n\n  /**\n   * Encodes the given type and its type annotations. The class comment for {@link TypeEncoder}\n   * covers the details of annotation encoding.\n   */\n  static String encodeWithAnnotations(AnnotatedTypeMirror type) {\n    return encodeWithAnnotations(type, ImmutableList.of(), ImmutableSet.of());\n  }\n\n  /**\n   * Encodes the given type and its type annotations. The class comment for {@link TypeEncoder}\n   * covers the details of annotation encoding.\n   *\n   * @param extraAnnotations additional type annotations to include with the type\n   */\n  static String encodeWithAnnotations(\n      TypeMirror type, ImmutableList<AnnotationMirror> extraAnnotations) {\n    return encodeWithAnnotations(type, extraAnnotations, ImmutableSet.of());\n  }\n\n  /**\n   * Encodes the given type and its type annotations. The class comment for {@link TypeEncoder}\n   * covers the details of annotation encoding.\n   *\n   * @param extraAnnotations additional type annotations to include with the type\n   */\n  static String encodeWithAnnotations(\n      AnnotatedTypeMirror type, ImmutableList<AnnotationMirror> extraAnnotations) {\n    return encodeWithAnnotations(type, extraAnnotations, ImmutableSet.of());\n  }\n\n  /**\n   * Encodes the given type and its type annotations. The class comment for {@link TypeEncoder}\n   * covers the details of annotation encoding.\n   *\n   * @param extraAnnotations additional type annotations to include with the type\n   * @param excludedAnnotationTypes annotations not to include in the encoding. For example, if\n   *     {@code com.example.Nullable} is in this set then the encoding will not include this\n   *     {@code @Nullable} annotation.\n   */\n  private static String encodeWithAnnotations(\n      TypeMirror type,\n      ImmutableList<AnnotationMirror> extraAnnotations,\n      Set<TypeMirror> excludedAnnotationTypes) {\n    StringBuilder sb = new StringBuilder();\n    // A function that is equivalent to t.getAnnotationMirrors() except when the t in question is\n    // our starting type. In that case we also add extraAnnotations to the result.\n    Function<TypeMirror, List<? extends AnnotationMirror>> getTypeAnnotations =\n        t ->\n            (t == type)\n                ? ImmutableList.<AnnotationMirror>builder()\n                    .addAll(t.getAnnotationMirrors())\n                    .addAll(extraAnnotations)\n                    .build()\n                : t.getAnnotationMirrors();\n    return new AnnotatedEncodingTypeVisitor(excludedAnnotationTypes, getTypeAnnotations)\n        .visit2(type, sb)\n        .toString();\n  }\n\n  /**\n   * Encodes the given type and its type annotations. The class comment for {@link TypeEncoder}\n   * covers the details of annotation encoding.\n   *\n   * @param extraAnnotations additional type annotations to include with the type\n   * @param excludedAnnotationTypes annotations not to include in the encoding. For example, if\n   *     {@code com.example.Nullable} is in this set then the encoding will not include this\n   *     {@code @Nullable} annotation.\n   */\n  static String encodeWithAnnotations(\n      AnnotatedTypeMirror type,\n      ImmutableList<AnnotationMirror> extraAnnotations,\n      Set<TypeMirror> excludedAnnotationTypes) {\n    StringBuilder sb = new StringBuilder();\n    // A function that is equivalent to t.getAnnotationMirrors() except when the t in question is\n    // our starting type. In that case we also add extraAnnotations to the result.\n    Function<TypeMirror, List<? extends AnnotationMirror>> getTypeAnnotations =\n        t ->\n            (t == type.getType())\n                ? ImmutableList.<AnnotationMirror>builder()\n                    .addAll(type.annotations())\n                    .addAll(extraAnnotations)\n                    .build()\n                : t.getAnnotationMirrors();\n    return new AnnotatedEncodingTypeVisitor(excludedAnnotationTypes, getTypeAnnotations)\n        .visit2(type.getType(), sb)\n        .toString();\n  }\n\n  /**\n   * Decodes the given string, respelling class names appropriately. The text is scanned for tokens\n   * like {@code `java.util.Locale`} or {@code `«java.util.Locale`} to determine which classes are\n   * referenced. An appropriate set of imports is computed based on the set of those types. If the\n   * special token {@code `import`} appears in {@code text} then it will be replaced by this set of\n   * import statements. Then all of the tokens are replaced by the class names they represent,\n   * spelled appropriately given the import statements.\n   *\n   * @param text the text to be decoded.\n   * @param packageName the package of the generated class. Other classes in the same package do not\n   *     need to be imported.\n   * @param baseType a class or interface that the generated class inherits from. Nested classes in\n   *     that type do not need to be imported, and if another class has the same name as one of\n   *     those nested classes then it will need to be qualified.\n   */\n  static String decode(\n      String text, ProcessingEnvironment processingEnv, String packageName, TypeMirror baseType) {\n    return decode(\n        text, processingEnv.getElementUtils(), processingEnv.getTypeUtils(), packageName, baseType);\n  }\n\n  static String decode(\n      String text, Elements elementUtils, Types typeUtils, String pkg, TypeMirror baseType) {\n    TypeRewriter typeRewriter = new TypeRewriter(text, elementUtils, typeUtils, pkg, baseType);\n    return typeRewriter.rewrite();\n  }\n\n  private static String className(DeclaredType declaredType) {\n    return MoreElements.asType(declaredType.asElement()).getQualifiedName().toString();\n  }\n\n  /**\n   * Returns a string representing the given type parameters as they would appear in a class\n   * declaration. For example, if we have {@code @AutoValue abstract class Foo<T extends SomeClass>}\n   * then if we call {@link TypeElement#getTypeParameters()} on the representation of {@code Foo},\n   * this method will return an encoding of {@code <T extends SomeClass>}. Likewise it will return\n   * an encoding of the angle-bracket part of: <br>\n   * {@code Foo<SomeClass>}<br>\n   * {@code Foo<T extends Number>}<br>\n   * {@code Foo<E extends Enum<E>>}<br>\n   * {@code Foo<K, V extends Comparable<? extends K>>}.\n   *\n   * <p>The encoding is simply that classes in the \"extends\" part are marked, so the examples will\n   * actually look something like this:<br>\n   * {@code <`bar.baz.SomeClass`>}<br>\n   * {@code <T extends `java.lang.Number`>}<br>\n   * {@code <E extends `java.lang.Enum`<E>>}<br>\n   * {@code <K, V extends `java.lang.Comparable`<? extends K>>}.\n   */\n  static String typeParametersString(List<? extends TypeParameterElement> typeParameters) {\n    if (typeParameters.isEmpty()) {\n      return \"\";\n    } else {\n      StringBuilder sb = new StringBuilder(\"<\");\n      String sep = \"\";\n      for (TypeParameterElement typeParameter : typeParameters) {\n        sb.append(sep);\n        sep = \", \";\n        appendTypeParameterWithBounds(typeParameter, sb);\n      }\n      return sb.append(\">\").toString();\n    }\n  }\n\n  private static void appendTypeParameterWithBounds(\n      TypeParameterElement typeParameter, StringBuilder sb) {\n    appendAnnotations(typeParameter.getAnnotationMirrors(), sb);\n    sb.append(typeParameter.getSimpleName());\n    String sep = \" extends \";\n    for (TypeMirror bound : typeParameter.getBounds()) {\n      if (!isUnannotatedJavaLangObject(bound)) {\n        sb.append(sep);\n        sep = \" & \";\n        sb.append(encodeWithAnnotations(bound));\n      }\n    }\n  }\n\n  // We can omit \"extends Object\" from a type bound, but not \"extends @NullableType Object\".\n  private static boolean isUnannotatedJavaLangObject(TypeMirror type) {\n    return type.getKind().equals(TypeKind.DECLARED)\n        && type.getAnnotationMirrors().isEmpty()\n        && MoreTypes.asTypeElement(type).getQualifiedName().contentEquals(\"java.lang.Object\");\n  }\n\n  private static void appendAnnotations(\n      List<? extends AnnotationMirror> annotationMirrors, StringBuilder sb) {\n    for (AnnotationMirror annotationMirror : annotationMirrors) {\n      sb.append(AnnotationOutput.sourceFormForAnnotation(annotationMirror)).append(\" \");\n    }\n  }\n\n  /**\n   * Converts a type into a string, using standard Java syntax, except that every class name is\n   * wrapped in backquotes, like {@code `java.util.List`}.\n   */\n  private static class EncodingTypeVisitor\n      extends SimpleTypeVisitor8<StringBuilder, StringBuilder> {\n    /**\n     * Equivalent to {@code visit(type, sb)} or {@code type.accept(sb)}, except that it fixes a bug\n     * with javac versions up to JDK 8, whereby if the type is a {@code DeclaredType} then the\n     * visitor is called with a version of the type where any annotations have been lost. We can't\n     * override {@code visit} because it is final.\n     */\n    StringBuilder visit2(TypeMirror type, StringBuilder sb) {\n      if (type.getKind().equals(TypeKind.DECLARED)) {\n        // There's no point in using MoreTypes.asDeclared here, and in fact we can't, because it\n        // uses a visitor, so it would trigger the bug we're working around.\n        return visitDeclared((DeclaredType) type, sb);\n      } else {\n        return visit(type, sb);\n      }\n    }\n\n    @Override\n    protected StringBuilder defaultAction(TypeMirror type, StringBuilder sb) {\n      return sb.append(type);\n    }\n\n    @Override\n    public StringBuilder visitArray(ArrayType type, StringBuilder sb) {\n      return visit2(type.getComponentType(), sb).append(\"[]\");\n    }\n\n    @Override\n    public StringBuilder visitDeclared(DeclaredType type, StringBuilder sb) {\n      appendTypeName(type, sb);\n      appendTypeArguments(type, sb);\n      return sb;\n    }\n\n    void appendTypeName(DeclaredType type, StringBuilder sb) {\n      TypeMirror enclosing = EclipseHack.getEnclosingType(type);\n      if (enclosing.getKind().equals(TypeKind.DECLARED)) {\n        // We might have something like com.example.Outer<Double>.Inner. We need to encode\n        // com.example.Outer<Double> first, producing `com.example.Outer`<`java.lang.Double`>.\n        // Then we can simply add .Inner after that. If Inner has its own type arguments, we'll\n        // add them with appendTypeArguments below. Of course, it's more usual for the outer class\n        // not to have type arguments, but we'll still follow this path if the nested class is an\n        // inner (not static) class.\n        visit2(enclosing, sb);\n        sb.append(\".\").append(type.asElement().getSimpleName());\n      } else {\n        sb.append('`').append(className(type)).append('`');\n      }\n    }\n\n    void appendTypeArguments(DeclaredType type, StringBuilder sb) {\n      List<? extends TypeMirror> arguments = type.getTypeArguments();\n      if (!arguments.isEmpty()) {\n        sb.append(\"<\");\n        String sep = \"\";\n        for (TypeMirror argument : arguments) {\n          sb.append(sep);\n          sep = \", \";\n          visit2(argument, sb);\n        }\n        sb.append(\">\");\n      }\n    }\n\n    @Override\n    public StringBuilder visitWildcard(WildcardType type, StringBuilder sb) {\n      sb.append(\"?\");\n      TypeMirror extendsBound = type.getExtendsBound();\n      TypeMirror superBound = type.getSuperBound();\n      if (superBound != null) {\n        sb.append(\" super \");\n        visit2(superBound, sb);\n      } else if (extendsBound != null) {\n        sb.append(\" extends \");\n        visit2(extendsBound, sb);\n      }\n      return sb;\n    }\n\n    @Override\n    public StringBuilder visitError(ErrorType t, StringBuilder p) {\n      throw new MissingTypeException(t);\n    }\n  }\n\n  /** Like {@link EncodingTypeVisitor} except that type parameters are omitted from the result. */\n  private static class RawEncodingTypeVisitor extends EncodingTypeVisitor {\n    @Override\n    void appendTypeArguments(DeclaredType type, StringBuilder sb) {}\n  }\n\n  /**\n   * Like {@link EncodingTypeVisitor} except that annotations on the visited type are also included\n   * in the resultant string. Class names in those annotations are also encoded using the {@code\n   * `java.util.List`} form.\n   */\n  private static class AnnotatedEncodingTypeVisitor extends EncodingTypeVisitor {\n    private final Set<TypeMirror> excludedAnnotationTypes;\n    private final Function<TypeMirror, List<? extends AnnotationMirror>> getTypeAnnotations;\n\n    AnnotatedEncodingTypeVisitor(\n        Set<TypeMirror> excludedAnnotationTypes,\n        Function<TypeMirror, List<? extends AnnotationMirror>> getTypeAnnotations) {\n      this.excludedAnnotationTypes = excludedAnnotationTypes;\n      this.getTypeAnnotations = getTypeAnnotations;\n    }\n\n    private void appendAnnotationsWithExclusions(\n        List<? extends AnnotationMirror> annotations, StringBuilder sb) {\n      // Optimization for the very common cases where there are no annotations or there are no\n      // exclusions.\n      if (annotations.isEmpty() || excludedAnnotationTypes.isEmpty()) {\n        appendAnnotations(annotations, sb);\n        return;\n      }\n      List<AnnotationMirror> includedAnnotations =\n          annotations.stream()\n              .filter(a -> !excludedAnnotationTypes.contains(a.getAnnotationType()))\n              .collect(toList());\n      appendAnnotations(includedAnnotations, sb);\n    }\n\n    @Override\n    public StringBuilder visitPrimitive(PrimitiveType type, StringBuilder sb) {\n      appendAnnotationsWithExclusions(getTypeAnnotations.apply(type), sb);\n      // We can't just append type.toString(), because that will also have the annotation, but\n      // without encoding.\n      return sb.append(type.getKind().toString().toLowerCase());\n    }\n\n    @Override\n    public StringBuilder visitTypeVariable(TypeVariable type, StringBuilder sb) {\n      appendAnnotationsWithExclusions(getTypeAnnotations.apply(type), sb);\n      return sb.append(type.asElement().getSimpleName());\n    }\n\n    /**\n     * {@inheritDoc} The result respects the Java syntax, whereby {@code Foo @Bar []} is an\n     * annotation on the array type itself, while {@code @Bar Foo[]} would be an annotation on the\n     * component type.\n     */\n    @Override\n    public StringBuilder visitArray(ArrayType type, StringBuilder sb) {\n      visit2(type.getComponentType(), sb);\n      List<? extends AnnotationMirror> annotationMirrors = getTypeAnnotations.apply(type);\n      if (!annotationMirrors.isEmpty()) {\n        sb.append(\" \");\n        appendAnnotationsWithExclusions(annotationMirrors, sb);\n      }\n      return sb.append(\"[]\");\n    }\n\n    @Override\n    public StringBuilder visitDeclared(DeclaredType type, StringBuilder sb) {\n      List<? extends AnnotationMirror> annotationMirrors = getTypeAnnotations.apply(type);\n      if (annotationMirrors.isEmpty()) {\n        super.visitDeclared(type, sb);\n      } else {\n        TypeMirror enclosing = EclipseHack.getEnclosingType(type);\n        if (enclosing.getKind().equals(TypeKind.DECLARED)) {\n          // We have something like com.example.Outer<Double>.@Annot Inner.\n          // We'll recursively encode com.example.Outer<Double> first,\n          // which if it is also annotated might result in a mouthful like\n          // `«com.example.Outer`@`org.annots.Nullable``»com.example.Outer`<`java.lang.Double`> .\n          // That annotation will have been added by a recursive call to this method.\n          // Then we'll add the annotation on the .Inner class, which we know is there because\n          // annotationMirrors is not empty. That means we'll append .@`org.annots.Annot` Inner .\n          visit2(enclosing, sb);\n          sb.append(\".\");\n          appendAnnotationsWithExclusions(annotationMirrors, sb);\n          sb.append(type.asElement().getSimpleName());\n        } else {\n          // This isn't an inner class, so we have the simpler (but still complicated) case of\n          // needing to place the annotation correctly in cases like java.util.@Nullable Map .\n          // See the class doc comment for an explanation of « and » here.\n          String className = className(type);\n          sb.append(\"`«\").append(className).append(\"`\");\n          appendAnnotationsWithExclusions(annotationMirrors, sb);\n          sb.append(\"`»\").append(className).append(\"`\");\n        }\n        appendTypeArguments(type, sb);\n      }\n      return sb;\n    }\n  }\n\n  private static class TypeRewriter {\n    private final String text;\n    private final int textLength;\n    private final JavaScanner scanner;\n    private final Elements elementUtils;\n    private final Types typeUtils;\n    private final String packageName;\n    private final TypeMirror baseType;\n\n    TypeRewriter(\n        String text, Elements elementUtils, Types typeUtils, String pkg, TypeMirror baseType) {\n      this.text = text;\n      this.textLength = text.length();\n      this.scanner = new JavaScanner(text);\n      this.elementUtils = elementUtils;\n      this.typeUtils = typeUtils;\n      this.packageName = pkg;\n      this.baseType = baseType;\n    }\n\n    String rewrite() {\n      // Scan the text to determine what classes are referenced.\n      Set<TypeMirror> referencedClasses = findReferencedClasses();\n      // Make a type simplifier based on these referenced types.\n      TypeSimplifier typeSimplifier =\n          new TypeSimplifier(elementUtils, typeUtils, packageName, referencedClasses, baseType);\n\n      StringBuilder output = new StringBuilder();\n      int copyStart;\n\n      // Replace the `import` token with the import statements, if it is present.\n      OptionalInt importMarker = findImportMarker();\n      if (importMarker.isPresent()) {\n        output.append(text, 0, importMarker.getAsInt());\n        for (String toImport : typeSimplifier.typesToImport()) {\n          output.append(\"import \").append(toImport).append(\";\\n\");\n        }\n        copyStart = scanner.tokenEnd(importMarker.getAsInt());\n      } else {\n        copyStart = 0;\n      }\n\n      // Replace each of the classname tokens with the appropriate spelling of the classname.\n      int token;\n      for (token = copyStart; token < textLength; token = scanner.tokenEnd(token)) {\n        if (text.charAt(token) == '`') {\n          output.append(text, copyStart, token);\n          decode(output, typeSimplifier, token);\n          copyStart = scanner.tokenEnd(token);\n        }\n      }\n      output.append(text, copyStart, textLength);\n      return output.toString();\n    }\n\n    private Set<TypeMirror> findReferencedClasses() {\n      Set<TypeMirror> classes = new TypeMirrorSet();\n      for (int token = 0; token < textLength; token = scanner.tokenEnd(token)) {\n        if (text.charAt(token) == '`' && !text.startsWith(\"`import`\", token)) {\n          String className = classNameAt(token);\n          classes.add(classForName(className));\n        }\n      }\n      return classes;\n    }\n\n    private DeclaredType classForName(String className) {\n      TypeElement typeElement = elementUtils.getTypeElement(className);\n      checkState(typeElement != null, \"Could not find referenced class %s\", className);\n      return MoreTypes.asDeclared(typeElement.asType());\n    }\n\n    private void decode(StringBuilder output, TypeSimplifier typeSimplifier, int token) {\n      String className = classNameAt(token);\n      DeclaredType type = classForName(className);\n      String simplified = typeSimplifier.simplifiedClassName(type);\n      int dot;\n      switch (text.charAt(token + 1)) {\n        case '«':\n          // If this is `«java.util.Map` then we want \"java.util.\" here.\n          // That's because this is the first part of something like \"java.util.@Nullable Map\"\n          // or \"java.util.Map.@Nullable Entry\".\n          // If there's no dot, then we want nothing here, for \"@Nullable Map\".\n          dot = simplified.lastIndexOf('.');\n          output.append(simplified.substring(0, dot + 1)); // correct even if dot == -1\n          break;\n        case '»':\n          dot = simplified.lastIndexOf('.');\n          output.append(simplified.substring(dot + 1)); // correct even if dot == -1\n          break;\n        default:\n          output.append(simplified);\n          break;\n      }\n    }\n\n    private OptionalInt findImportMarker() {\n      for (int token = 0; token < textLength; token = scanner.tokenEnd(token)) {\n        if (text.startsWith(\"`import`\", token)) {\n          return OptionalInt.of(token);\n        }\n      }\n      return OptionalInt.empty();\n    }\n\n    private String classNameAt(int token) {\n      checkArgument(text.charAt(token) == '`');\n      int end = scanner.tokenEnd(token) - 1; // points to the closing `\n      int t = token + 1;\n      char c = text.charAt(t);\n      if (c == '«' || c == '»') {\n        t++;\n      }\n      return text.substring(t, end);\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/TypeMirrorSet.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.common.base.Equivalence;\nimport com.google.common.collect.ImmutableList;\nimport java.util.AbstractSet;\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.LinkedHashSet;\nimport java.util.Set;\nimport javax.lang.model.type.TypeMirror;\n\n/**\n * A set of TypeMirror objects.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\nclass TypeMirrorSet extends AbstractSet<TypeMirror> {\n  private final Set<Equivalence.Wrapper<TypeMirror>> wrappers = new LinkedHashSet<>();\n\n  TypeMirrorSet() {}\n\n  TypeMirrorSet(Collection<? extends TypeMirror> types) {\n    addAll(types);\n  }\n\n  static TypeMirrorSet of(TypeMirror... types) {\n    return new TypeMirrorSet(ImmutableList.copyOf(types));\n  }\n\n  private Equivalence.Wrapper<TypeMirror> wrap(TypeMirror typeMirror) {\n    return MoreTypes.equivalence().wrap(typeMirror);\n  }\n\n  @Override\n  public boolean add(TypeMirror typeMirror) {\n    return wrappers.add(wrap(typeMirror));\n  }\n\n  @Override\n  public Iterator<TypeMirror> iterator() {\n    final Iterator<Equivalence.Wrapper<TypeMirror>> iterator = wrappers.iterator();\n    return new Iterator<TypeMirror>() {\n      @Override\n      public boolean hasNext() {\n        return iterator.hasNext();\n      }\n\n      @Override\n      public TypeMirror next() {\n        return iterator.next().get();\n      }\n\n      @Override\n      public void remove() {\n        iterator.remove();\n      }\n    };\n  }\n\n  @Override\n  public int size() {\n    return wrappers.size();\n  }\n\n  @Override\n  public boolean contains(Object o) {\n    if (o instanceof TypeMirror) {\n      return wrappers.contains(wrap((TypeMirror) o));\n    } else {\n      return false;\n    }\n  }\n\n  @Override\n  public boolean remove(Object o) {\n    if (o instanceof TypeMirror) {\n      return wrappers.remove(wrap((TypeMirror) o));\n    } else {\n      return false;\n    }\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o instanceof TypeMirrorSet) {\n      TypeMirrorSet that = (TypeMirrorSet) o;\n      return wrappers.equals(that.wrappers);\n    } else {\n      return false;\n    }\n  }\n\n  @Override\n  public int hashCode() {\n    return wrappers.hashCode();\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/TypeSimplifier.java",
    "content": "/*\n * Copyright 2012 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static java.util.stream.Collectors.joining;\nimport static java.util.stream.Collectors.toCollection;\nimport static javax.lang.model.element.Modifier.PRIVATE;\n\nimport com.google.auto.common.MoreElements;\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.value.processor.MissingTypes.MissingTypeException;\nimport com.google.common.collect.ImmutableSortedSet;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.lang.model.element.Name;\nimport javax.lang.model.element.NestingKind;\nimport javax.lang.model.element.QualifiedNameable;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.TypeParameterElement;\nimport javax.lang.model.type.ArrayType;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.type.TypeVariable;\nimport javax.lang.model.type.TypeVisitor;\nimport javax.lang.model.type.WildcardType;\nimport javax.lang.model.util.ElementFilter;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.SimpleTypeVisitor8;\nimport javax.lang.model.util.Types;\n\n/**\n * Takes a set of types and a package and determines which of those types can be imported, and how\n * to spell any of the types in the set given those imports.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\nfinal class TypeSimplifier {\n  /**\n   * The spelling that should be used to refer to a given class, and an indication of whether it\n   * should be imported.\n   */\n  private static class Spelling {\n    final String spelling;\n    final boolean importIt;\n\n    Spelling(String spelling, boolean importIt) {\n      this.spelling = spelling;\n      this.importIt = importIt;\n    }\n  }\n\n  private final Map<String, Spelling> imports;\n\n  /**\n   * Makes a new simplifier for the given package and set of types.\n   *\n   * @param elementUtils the result of {@code ProcessingEnvironment.getElementUtils()} for the\n   *     current annotation processing environment.\n   * @param typeUtils the result of {@code ProcessingEnvironment.getTypeUtils()} for the current\n   *     annotation processing environment.\n   * @param packageName the name of the package from which classes will be referenced. Classes that\n   *     are in the same package do not need to be imported.\n   * @param types the types that will be referenced.\n   * @param base a base class that the class containing the references will extend. This is needed\n   *     because nested classes in that class or one of its ancestors are in scope in the generated\n   *     subclass, so a reference to another class with the same name as one of them is ambiguous.\n   * @throws MissingTypeException if one of the input types contains an error (typically, is\n   *     undefined).\n   */\n  TypeSimplifier(\n      Elements elementUtils,\n      Types typeUtils,\n      String packageName,\n      Set<TypeMirror> types,\n      TypeMirror base) {\n    Set<TypeMirror> typesPlusBase = new TypeMirrorSet(types);\n    if (base != null) {\n      typesPlusBase.add(base);\n    }\n    Set<TypeMirror> topLevelTypes = topLevelTypes(typeUtils, typesPlusBase);\n    Set<TypeMirror> defined = nonPrivateDeclaredTypes(typeUtils, base);\n    this.imports = findImports(elementUtils, typeUtils, packageName, topLevelTypes, defined);\n  }\n\n  /**\n   * Returns the set of types to import. We import every type that is neither in java.lang nor in\n   * the package containing the AutoValue class, provided that the result refers to the type\n   * unambiguously. For example, if there is a property of type java.util.Map.Entry then we will\n   * import java.util.Map.Entry and refer to the property as Entry. We could also import just\n   * java.util.Map in this case and refer to Map.Entry, but currently we never do that.\n   */\n  ImmutableSortedSet<String> typesToImport() {\n    ImmutableSortedSet.Builder<String> typesToImport = ImmutableSortedSet.naturalOrder();\n    for (Map.Entry<String, Spelling> entry : imports.entrySet()) {\n      if (entry.getValue().importIt) {\n        typesToImport.add(entry.getKey());\n      }\n    }\n    return typesToImport.build();\n  }\n\n  String simplifiedClassName(DeclaredType type) {\n    TypeElement typeElement = MoreElements.asType(type.asElement());\n    TypeElement top = topLevelType(typeElement);\n    // We always want to write a class name starting from the outermost class. For example,\n    // if the type is java.util.Map.Entry then we will import java.util.Map and write Map.Entry.\n    String topString = top.getQualifiedName().toString();\n    if (imports.containsKey(topString)) {\n      String suffix = typeElement.getQualifiedName().toString().substring(topString.length());\n      return imports.get(topString).spelling + suffix;\n    } else {\n      return typeElement.getQualifiedName().toString();\n    }\n  }\n\n  // The actual type parameters of the given type.\n  // If we have @AutoValue abstract class Foo<T extends Something> then the subclass will be\n  // final class AutoValue_Foo<T extends Something> extends Foo<T>.\n  // <T extends Something> is the formal type parameter list and\n  // <T> is the actual type parameter list, which is what this method returns.\n  static String actualTypeParametersString(TypeElement type) {\n    List<? extends TypeParameterElement> typeParameters = type.getTypeParameters();\n    if (typeParameters.isEmpty()) {\n      return \"\";\n    } else {\n      return typeParameters.stream()\n          .map(e -> e.getSimpleName().toString())\n          .collect(joining(\", \", \"<\", \">\"));\n    }\n  }\n\n  /** Returns the name of the given type, including any enclosing types but not the package. */\n  static String classNameOf(TypeElement type) {\n    String name = type.getQualifiedName().toString();\n    String pkgName = packageNameOf(type);\n    return pkgName.isEmpty() ? name : name.substring(pkgName.length() + 1);\n  }\n\n  private static TypeElement topLevelType(TypeElement type) {\n    while (type.getNestingKind() != NestingKind.TOP_LEVEL) {\n      type = MoreElements.asType(type.getEnclosingElement());\n    }\n    return type;\n  }\n\n  /**\n   * Returns the name of the package that the given type is in. If the type is in the default\n   * (unnamed) package then the name is the empty string.\n   */\n  static String packageNameOf(TypeElement type) {\n    return MoreElements.getPackage(type).getQualifiedName().toString();\n  }\n\n  static String simpleNameOf(String s) {\n    if (s.contains(\".\")) {\n      return s.substring(s.lastIndexOf('.') + 1);\n    } else {\n      return s;\n    }\n  }\n\n  /**\n   * Given a set of referenced types, works out which of them should be imported and what the\n   * resulting spelling of each one is.\n   *\n   * <p>This method operates on a {@code Set<TypeMirror>} rather than just a {@code Set<String>}\n   * because it is not strictly possible to determine what part of a fully-qualified type name is\n   * the package and what part is the top-level class. For example, {@code java.util.Map.Entry} is a\n   * class called {@code Map.Entry} in a package called {@code java.util} assuming Java conventions\n   * are being followed, but it could theoretically also be a class called {@code Entry} in a\n   * package called {@code java.util.Map}. Since we are operating as part of the compiler, our goal\n   * should be complete correctness, and the only way to achieve that is to operate on the real\n   * representations of types.\n   *\n   * @param codePackageName The name of the package where the class containing these references is\n   *     defined. Other classes within the same package do not need to be imported.\n   * @param referenced The complete set of declared types (classes and interfaces) that will be\n   *     referenced in the generated code.\n   * @param defined The complete set of declared types (classes and interfaces) that are defined\n   *     within the scope of the generated class (i.e. nested somewhere in its superclass chain, or\n   *     in its interface set)\n   * @return a map where the keys are fully-qualified types and the corresponding values indicate\n   *     whether the type should be imported, and how the type should be spelled in the source code.\n   */\n  private static Map<String, Spelling> findImports(\n      Elements elementUtils,\n      Types typeUtils,\n      String codePackageName,\n      Set<TypeMirror> referenced,\n      Set<TypeMirror> defined) {\n    Map<String, Spelling> imports = new HashMap<>();\n    Set<TypeMirror> typesInScope = new TypeMirrorSet();\n    typesInScope.addAll(referenced);\n    typesInScope.addAll(defined);\n    Set<String> ambiguous = ambiguousNames(typeUtils, typesInScope);\n    for (TypeMirror type : referenced) {\n      TypeElement typeElement = (TypeElement) typeUtils.asElement(type);\n      String fullName = typeElement.getQualifiedName().toString();\n      String simpleName = typeElement.getSimpleName().toString();\n      String pkg = packageNameOf(typeElement);\n      boolean importIt;\n      String spelling;\n      if (ambiguous.contains(simpleName)) {\n        importIt = false;\n        spelling = fullName;\n      } else if (pkg.equals(\"java.lang\")) {\n        importIt = false;\n        spelling = javaLangSpelling(elementUtils, codePackageName, typeElement);\n      } else if (pkg.equals(codePackageName)) {\n        importIt = false;\n        spelling = fullName.substring(pkg.isEmpty() ? 0 : pkg.length() + 1);\n      } else {\n        importIt = true;\n        spelling = simpleName;\n      }\n      imports.put(fullName, new Spelling(spelling, importIt));\n    }\n    return imports;\n  }\n\n  /**\n   * Handles the tricky case where the class being referred to is in {@code java.lang}, but the\n   * package of the referring code contains another class of the same name. For example, if the\n   * current package is {@code foo.bar} and there is a {@code foo.bar.Compiler}, then we will refer\n   * to {@code java.lang.Compiler} by its full name. The plain name {@code Compiler} would reference\n   * {@code foo.bar.Compiler} in this case. We need to write {@code java.lang.Compiler} even if the\n   * other {@code Compiler} class is not being considered here, so the {@link #ambiguousNames} logic\n   * is not enough. We have to look to see if the class exists.\n   */\n  private static String javaLangSpelling(\n      Elements elementUtils, String codePackageName, TypeElement typeElement) {\n    // If this is java.lang.Thread.State or the like, we have to look for a clash with Thread.\n    TypeElement topLevelType = topLevelType(typeElement);\n    TypeElement clash =\n        elementUtils.getTypeElement(codePackageName + \".\" + topLevelType.getSimpleName());\n    String fullName = typeElement.getQualifiedName().toString();\n    return (clash == null) ? fullName.substring(\"java.lang.\".length()) : fullName;\n  }\n\n  /**\n   * Finds the top-level types for all the declared types (classes and interfaces) in the given\n   * {@code Set<TypeMirror>}.\n   *\n   * <p>The returned set contains only top-level types. If we reference {@code java.util.Map.Entry}\n   * then the returned set will contain {@code java.util.Map}. This is because we want to write\n   * {@code Map.Entry} everywhere rather than {@code Entry}.\n   */\n  private static Set<TypeMirror> topLevelTypes(Types typeUtil, Set<TypeMirror> types) {\n    return types.stream()\n        .map(typeMirror -> MoreElements.asType(typeUtil.asElement(typeMirror)))\n        .map(typeElement -> topLevelType(typeElement).asType())\n        .collect(toCollection(TypeMirrorSet::new));\n  }\n\n  /**\n   * Finds all types that are declared with non private visibility by the given {@code TypeMirror},\n   * any class in its superclass chain, or any interface it implements.\n   */\n  private static Set<TypeMirror> nonPrivateDeclaredTypes(Types typeUtils, TypeMirror type) {\n    if (type == null) {\n      return new TypeMirrorSet();\n    } else {\n      Set<TypeMirror> declared = new TypeMirrorSet();\n      declared.add(type);\n      List<TypeElement> nestedTypes =\n          ElementFilter.typesIn(typeUtils.asElement(type).getEnclosedElements());\n      for (TypeElement nestedType : nestedTypes) {\n        if (!nestedType.getModifiers().contains(PRIVATE)) {\n          declared.add(nestedType.asType());\n        }\n      }\n      for (TypeMirror supertype : typeUtils.directSupertypes(type)) {\n        declared.addAll(nonPrivateDeclaredTypes(typeUtils, supertype));\n      }\n      return declared;\n    }\n  }\n\n  private static Set<String> ambiguousNames(Types typeUtils, Set<TypeMirror> types) {\n    Set<String> ambiguous = new HashSet<>();\n    Map<String, Name> simpleNamesToQualifiedNames = new HashMap<>();\n    for (TypeMirror type : types) {\n      if (type.getKind() == TypeKind.ERROR) {\n        throw new MissingTypeException(MoreTypes.asError(type));\n      }\n      String simpleName = typeUtils.asElement(type).getSimpleName().toString();\n      /*\n       * Compare by qualified names, because in Eclipse JDT, if Java 8 type annotations are used,\n       * the same (unannotated) type may appear multiple times in the Set<TypeMirror>.\n       * TODO(emcmanus): investigate further, because this might cause problems elsewhere.\n       */\n      Name qualifiedName = ((QualifiedNameable) typeUtils.asElement(type)).getQualifiedName();\n      Name previous = simpleNamesToQualifiedNames.put(simpleName, qualifiedName);\n      if (previous != null && !previous.equals(qualifiedName)) {\n        ambiguous.add(simpleName);\n      }\n    }\n    return ambiguous;\n  }\n\n  /**\n   * Returns true if casting to the given type will elicit an unchecked warning from the compiler.\n   * Only generic types such as {@code List<String>} produce such warnings. There will be no warning\n   * if the type's only generic parameters are simple wildcards, as in {@code Map<?, ?>}.\n   */\n  static boolean isCastingUnchecked(TypeMirror type) {\n    return CASTING_UNCHECKED_VISITOR.visit(type, null);\n  }\n\n  private static final TypeVisitor<Boolean, Void> CASTING_UNCHECKED_VISITOR =\n      new SimpleTypeVisitor8<Boolean, Void>(false) {\n        @Override\n        public Boolean visitUnknown(TypeMirror t, Void p) {\n          // We don't know whether casting is unchecked for this mysterious type but assume it is,\n          // so we will insert a possibly unnecessary @SuppressWarnings(\"unchecked\").\n          return true;\n        }\n\n        @Override\n        public Boolean visitArray(ArrayType t, Void p) {\n          return visit(t.getComponentType(), p);\n        }\n\n        @Override\n        public Boolean visitDeclared(DeclaredType t, Void p) {\n          return t.getTypeArguments().stream().anyMatch(TypeSimplifier::uncheckedTypeArgument);\n        }\n\n        @Override\n        public Boolean visitTypeVariable(TypeVariable t, Void p) {\n          return true;\n        }\n      };\n\n  // If a type has a type argument, then casting to the type is unchecked, except if the argument\n  // is <?> or <? extends Object>. The same applies to all type arguments, so casting to Map<?, ?>\n  // does not produce an unchecked warning for example.\n  private static boolean uncheckedTypeArgument(TypeMirror arg) {\n    if (arg.getKind() == TypeKind.WILDCARD) {\n      WildcardType wildcard = (WildcardType) arg;\n      if (wildcard.getExtendsBound() == null || isJavaLangObject(wildcard.getExtendsBound())) {\n        // This is <?>, unless there's a super bound, in which case it is <? super Foo> and\n        // is erased.\n        return (wildcard.getSuperBound() != null);\n      }\n    }\n    return true;\n  }\n\n  private static boolean isJavaLangObject(TypeMirror type) {\n    if (type.getKind() != TypeKind.DECLARED) {\n      return false;\n    }\n    DeclaredType declaredType = (DeclaredType) type;\n    TypeElement typeElement = (TypeElement) declaredType.asElement();\n    return typeElement.getQualifiedName().contentEquals(\"java.lang.Object\");\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/TypeVariables.java",
    "content": "/*\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.collect.ImmutableMap.toImmutableMap;\n\nimport com.google.auto.common.MoreElements;\nimport com.google.auto.common.MoreTypes;\nimport com.google.common.base.Equivalence;\nimport com.google.common.base.Preconditions;\nimport com.google.common.collect.ImmutableMap;\nimport java.util.Collection;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.function.Function;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.Modifier;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.TypeParameterElement;\nimport javax.lang.model.type.ArrayType;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.type.TypeVariable;\nimport javax.lang.model.type.WildcardType;\nimport javax.lang.model.util.SimpleTypeVisitor8;\nimport javax.lang.model.util.Types;\n\n/** Methods for handling type variables. */\nfinal class TypeVariables {\n  private TypeVariables() {}\n\n  /**\n   * Returns a map from methods to return types, where the return types are not necessarily the\n   * original return types of the methods. Consider this example:\n   *\n   * <pre>{@code\n   * @AutoValue class Foo<T> {\n   *   abstract T getFoo();\n   *\n   *   @AutoValue.Builder\n   *   abstract class Builder<T> {\n   *     abstract Builder setFoo(T t);\n   *     abstract Foo<T> build();\n   *   }\n   * }\n   * }</pre>\n   *\n   * We want to be able to check that the parameter type of {@code setFoo} is the same as the return\n   * type of {@code getFoo}. But in fact it isn't, because the {@code T} of {@code Foo<T>} is not\n   * the same as the {@code T} of {@code Foo.Builder<T>}. So we create a parallel {@code Foo<T>}\n   * where the {@code T} <i>is</i> the one from {@code Foo.Builder<T>}. That way the types do\n   * correspond. This method then returns the return types of the given methods as they appear in\n   * that parallel class, meaning the type given for {@code getFoo()} is the {@code T} of {@code\n   * Foo.Builder<T>}.\n   *\n   * <p>We do the rewrite this way around (applying the type parameter from {@code Foo.Builder} to\n   * {@code Foo}) because if we hit one of the historical Eclipse bugs with {@link Types#asMemberOf}\n   * then {@link EclipseHack#methodReturnType} can use fallback logic, which only works for methods\n   * with no arguments.\n   *\n   * @param methods the methods whose return types are to be rewritten.\n   * @param sourceType the class containing those methods ({@code Foo} in the example).\n   * @param targetType the class to translate the methods into ({@code Foo.Builder<T>}) in the\n   *     example.\n   */\n  static ImmutableMap<ExecutableElement, AnnotatedTypeMirror> rewriteReturnTypes(\n      Types typeUtils,\n      Collection<ExecutableElement> methods,\n      TypeElement sourceType,\n      TypeElement targetType) {\n    List<? extends TypeParameterElement> sourceTypeParameters = sourceType.getTypeParameters();\n    List<? extends TypeParameterElement> targetTypeParameters = targetType.getTypeParameters();\n    Preconditions.checkArgument(\n        sourceTypeParameters.toString().equals(targetTypeParameters.toString()),\n        \"%s != %s\",\n        sourceTypeParameters,\n        targetTypeParameters);\n    // What we're doing is only valid if the type parameters are \"the same\". The check here even\n    // requires the names to be the same. The logic would still work without that, but we impose\n    // that requirement elsewhere and it means we can check in this simple way.\n    TypeMirror[] targetTypeParameterMirrors = new TypeMirror[targetTypeParameters.size()];\n    for (int i = 0; i < targetTypeParameters.size(); i++) {\n      targetTypeParameterMirrors[i] = targetTypeParameters.get(i).asType();\n    }\n    DeclaredType parallelSource = typeUtils.getDeclaredType(sourceType, targetTypeParameterMirrors);\n    return methods.stream()\n        .collect(\n            toImmutableMap(\n                m -> m,\n                m -> MethodSignature.asMemberOf(typeUtils, parallelSource, m).returnType()));\n  }\n\n  /**\n   * Tests whether a given parameter can be given to a static method like {@code\n   * ImmutableMap.copyOf} to produce a value that can be assigned to the given target type.\n   *\n   * <p>For example, suppose we have this method in {@code ImmutableMap}:<br>\n   * {@code static <K, V> ImmutableMap<K, V> copyOf(Map<? extends K, ? extends V>)}<br>\n   * and we want to know if we can do this:\n   *\n   * <pre>{@code\n   * ImmutableMap<String, Integer> actualParameter = ...;\n   * ImmutableMap<String, Number> target = ImmutableMap.copyOf(actualParameter);\n   * }</pre>\n   *\n   * We will infer {@code K=String}, {@code V=Number} based on the target type, and then rewrite the\n   * formal parameter type from<br>\n   * {@code Map<? extends K, ? extends V>} to<br>\n   * {@code Map<? extends String, ? extends Number>}. Then we can check whether {@code\n   * actualParameter} is assignable to that.\n   *\n   * <p>The logic makes some simplifying assumptions, which are met for the {@code copyOf} and\n   * {@code of} methods that we use this for. The method must be static, it must have exactly one\n   * parameter, and it must have type parameters without bounds that are the same as the type\n   * parameters of its return type. We can see that these assumptions are met for the {@code\n   * ImmutableMap.copyOf} example above.\n   */\n  static boolean canAssignStaticMethodResult(\n      ExecutableElement method,\n      TypeMirror actualParameterType,\n      TypeMirror targetType,\n      Types typeUtils) {\n    if (!targetType.getKind().equals(TypeKind.DECLARED)\n        || !method.getModifiers().contains(Modifier.STATIC)\n        || method.getParameters().size() != 1) {\n      return false;\n    }\n    List<? extends TypeParameterElement> typeParameters = method.getTypeParameters();\n    List<? extends TypeMirror> targetTypeArguments =\n        MoreTypes.asDeclared(targetType).getTypeArguments();\n    if (typeParameters.size() != targetTypeArguments.size()) {\n      return false;\n    }\n    Map<Equivalence.Wrapper<TypeVariable>, TypeMirror> typeVariables = new LinkedHashMap<>();\n    for (int i = 0; i < typeParameters.size(); i++) {\n      TypeVariable v = MoreTypes.asTypeVariable(typeParameters.get(i).asType());\n      typeVariables.put(MoreTypes.equivalence().wrap(v), targetTypeArguments.get(i));\n    }\n    Function<TypeVariable, TypeMirror> substitute =\n        v -> typeVariables.get(MoreTypes.equivalence().wrap(v));\n    TypeMirror formalParameterType = method.getParameters().get(0).asType();\n    SubstitutionVisitor substitutionVisitor = new SubstitutionVisitor(substitute, typeUtils);\n    TypeMirror substitutedParameterType = substitutionVisitor.visit(formalParameterType, null);\n    if (substitutedParameterType.getKind().equals(TypeKind.WILDCARD)) {\n      // If the target type is Optional<? extends Foo> then <T> T Optional.of(T) will give us\n      // ? extends Foo here, and typeUtils.isAssignable will return false. But we can in fact\n      // give a Foo as an argument, so we just replace ? extends Foo with Foo.\n      WildcardType wildcard = MoreTypes.asWildcard(substitutedParameterType);\n      if (wildcard.getExtendsBound() != null) {\n        substitutedParameterType = wildcard.getExtendsBound();\n      }\n    }\n    return typeUtils.isAssignable(actualParameterType, substitutedParameterType);\n  }\n\n  static TypeMirror substituteTypeVariables(\n      TypeMirror input, Function<TypeVariable, TypeMirror> substitute, Types typeUtils) {\n    SubstitutionVisitor substitutionVisitor = new SubstitutionVisitor(substitute, typeUtils);\n    return substitutionVisitor.visit(input, null);\n  }\n\n  /**\n   * Rewrites types such that references to type variables in the given map are replaced by the\n   * values of those variables.\n   */\n  private static class SubstitutionVisitor extends SimpleTypeVisitor8<TypeMirror, Void> {\n    private final Function<TypeVariable, TypeMirror> substitute;\n    private final Types typeUtils;\n\n    SubstitutionVisitor(Function<TypeVariable, TypeMirror> substitute, Types typeUtils) {\n      this.substitute = substitute;\n      this.typeUtils = typeUtils;\n    }\n\n    @Override\n    protected TypeMirror defaultAction(TypeMirror t, Void p) {\n      return t;\n    }\n\n    @Override\n    public TypeMirror visitTypeVariable(TypeVariable t, Void p) {\n      TypeMirror substituted = substitute.apply(t);\n      return (substituted == null) ? t : substituted;\n    }\n\n    @Override\n    public TypeMirror visitDeclared(DeclaredType t, Void p) {\n      List<? extends TypeMirror> typeArguments = t.getTypeArguments();\n      TypeMirror[] substitutedTypeArguments = new TypeMirror[typeArguments.size()];\n      for (int i = 0; i < typeArguments.size(); i++) {\n        substitutedTypeArguments[i] = visit(typeArguments.get(i));\n      }\n      return typeUtils.getDeclaredType(\n          MoreElements.asType(t.asElement()), substitutedTypeArguments);\n    }\n\n    @Override\n    public TypeMirror visitWildcard(WildcardType t, Void p) {\n      TypeMirror ext = visitOrNull(t.getExtendsBound());\n      if (ext != null && ext.getKind().equals(TypeKind.WILDCARD)) {\n        // An example of where this happens is if we have this method in ImmutableSet:\n        //    static <E> ImmutableSet<E> copyOf(Collection<? extends E>)\n        // and we want to know if we can do this (where T is parameter of the enclosing class):\n        //    ImmutableSet<T> actualParameter = ...\n        //    ImmutableSet<? extends T> target = ImmutableSet.copyOf(actualParameter);\n        // We will infer E=<? extends T> and rewrite the formal parameter type to\n        // Collection<? extends ? extends T>, which we must simplify to Collection<? extends T>.\n        return ext;\n      }\n      return typeUtils.getWildcardType(ext, visitOrNull(t.getSuperBound()));\n    }\n\n    @Override\n    public TypeMirror visitArray(ArrayType t, Void p) {\n      TypeMirror comp = visit(t.getComponentType());\n      if (comp.getKind().equals(TypeKind.WILDCARD)) {\n        // An example of where this happens is if we have this method in ImmutableSet:\n        //    static <E> ImmutableSet<E> copyOf(E[])\n        // and we want to know if we can do this:\n        //    String[] actualParameter = ...\n        //    ImmutableSet<? extends T> target = ImmutableSet.copyOf(actualParameter);\n        // We will infer E=<? extends T> and rewrite the formal parameter type to\n        // <? extends T>[], which we must simplify to T[].\n        // TODO: what if getExtendsBound() returns null?\n        comp = MoreTypes.asWildcard(comp).getExtendsBound();\n      }\n      return typeUtils.getArrayType(comp);\n    }\n\n    // We'd like to override visitIntersectionType here for completeness, but Types has no method\n    // to fabricate a new IntersectionType. Anyway, currently IntersectionType can only occur as\n    // the result of TypeVariable.getUpperBound(), but the TypeMirror we're starting from is not\n    // that, and if we encounter a TypeVariable during our visit we don't visit its upper bound.\n\n    private TypeMirror visitOrNull(TypeMirror t) {\n      if (t == null) {\n        return null;\n      } else {\n        return visit(t);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/autoannotation.vm",
    "content": "## Copyright 2014 Google LLC\n##\n## Licensed under the Apache License, Version 2.0 (the \"License\");\n## you may not use this file except in compliance with the License.\n## You may obtain a copy of the License at\n##\n## http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n\n## Template for each generated AutoAnnotation_Foo_bar class.\n## This template uses the Apache Velocity Template Language (VTL).\n## The variables ($pkg, $props, and so on) are defined by the fields of AutoAnnotationTemplateVars.\n##\n## Comments, like this one, begin with ##. The comment text extends up to and including the newline\n## character at the end of the line. So comments also serve to join a line to the next one.\n## Velocity deletes a newline after a directive (#if, #foreach, #end etc) so ## is not needed there.\n## That does mean that we sometimes need an extra blank line after such a directive.\n##\n## Post-processing will remove unwanted spaces and blank lines, but will not join two lines.\n## It will also replace classes spelled as (e.g.) `java.util.Arrays`, with the backquotes, to\n## use just Arrays if that class can be imported unambiguously, or java.util.Arrays if not.\n\n#macro (cloneArray $a)\n  #if ($gwtCompatible)\n    `java.util.Arrays`.copyOf($a, ${a}.length)\n  #else\n    ${a}.clone()\n  #end\n#end\n\n#if (!$pkg.empty)\npackage $pkg;\n#end\n\n## The following line will be replaced by the required imports during post-processing.\n`import`\n\n#if (!$generated.empty)\n@${generated}(\"com.google.auto.value.processor.AutoAnnotationProcessor\")\n#else\n// Generated by com.google.auto.value.processor.AutoAnnotationProcessor\n#end\nfinal class $className implements $annotationName, `java.io.Serializable` {\n  private static final long serialVersionUID = ${serialVersionUID}L;\n\n## Fields\n\n#foreach ($m in $members)\n  #if ($params.containsKey($m.toString()))\n\n  private final $m.type $m;\n\n  #else\n\n  private static final $m.type $m = $m.defaultValue;\n\n  #end\n#end\n\n## Constructor\n\n  $className(\n#foreach ($p in $params.keySet())\n\n      $params[$p].type $members[$p] #if ($foreach.hasNext) , #end\n#end ) {\n#foreach ($p in $params.keySet())\n  #if (!$members[$p].kind.primitive)\n\n    if ($p == null) {\n      throw new NullPointerException(\"Null $p\");\n    }\n\n  #end\n\n  #if ($members[$p].kind == \"ARRAY\")\n    #if ($params[$p].kind == \"ARRAY\")\n\n    this.$p = #cloneArray(${p});\n\n    #elseif ($members[$p].typeMirror.componentType.kind.primitive)\n\n    this.$p = ${members[$p].typeMirror.componentType}ArrayFromCollection($p);\n\n    #elseif ($members[$p].arrayOfClassWithBounds)\n\n    @SuppressWarnings({\"unchecked\", \"rawtypes\"})\n    ${members[$p].componentType}[] ${p}$ = ${p}.toArray(new Class[0]);\n    this.$p = ${p}$;\n\n    #else\n\n    this.$p = ${p}.toArray(new ${members[$p].componentType}[0]);\n\n    #end\n  #else\n\n    this.$p = $p;\n\n  #end\n#end\n\n  }\n\n## annotationType method (defined by the Annotation interface)\n\n  @`java.lang.Override`\n  public Class<? extends $annotationName> annotationType() {\n    return ${annotationName}.class;\n  }\n\n## Member getters\n\n#foreach ($m in $members)\n\n  @`java.lang.Override`\n  public ${m.type} ${m}() {\n\n  #if ($m.kind == \"ARRAY\")\n\n    return #cloneArray(${m});\n\n  #else\n\n    return ${m};\n\n  #end\n\n  }\n\n#end\n\n## toString\n\n#macro (appendMemberString $m)\n  #if ($m.typeMirror.toString() == \"java.lang.String\")\n    #set ($appendQuotedStringMethod = \"true\")\n\n    appendQuoted(sb, $m) ##\n  #elseif ($m.typeMirror.toString() == \"char\")\n    #set ($appendQuotedCharMethod = \"true\")\n\n    appendQuoted(sb, $m) ##\n  #elseif ($m.typeMirror.toString() == \"java.lang.String[]\")\n    #set ($appendQuotedStringArrayMethod = \"true\")\n\n    appendQuoted(sb, $m) ##\n  #elseif ($m.typeMirror.toString() == \"char[]\")\n    #set ($appendQuotedCharArrayMethod = \"true\")\n\n    appendQuoted(sb, $m) ##\n  #elseif ($m.kind == \"ARRAY\")\n\n    sb.append(`java.util.Arrays`.toString($m)) ##\n  #else\n\n    sb.append($m) ##\n  #end\n#end\n\n  @`java.lang.Override`\n  public String toString() {\n    StringBuilder sb = new StringBuilder(\"@$annotationFullName(\");\n\n  #foreach ($p in $params.keySet())\n\n    #if ($params.size() > 1 || $params.keySet().iterator().next() != \"value\")\n\n    sb.append(\"$p=\");\n    #end\n\n    #appendMemberString($members[$p]);\n\n    #if ($foreach.hasNext)\n\n    sb.append(\", \");\n    #end\n\n  #end\n\n    return sb.append(')').toString();\n  }\n\n## equals\n\n## An expression that compares `this.something` against `that.something()`.\n## It can appear in a chain of && conditions, so if that would cause precedence\n## problems the expression needs to be parenthesized.\n#macro (memberEqualsThatExpression $m)\n  #if ($m.kind == \"FLOAT\")\n    Float.floatToIntBits($m) == Float.floatToIntBits(that.${m}()) ##\n  #elseif ($m.kind == \"DOUBLE\")\n    Double.doubleToLongBits($m) == Double.doubleToLongBits(that.${m}()) ##\n  #elseif ($m.kind.primitive)\n    ($m == that.${m}()) ## parens not strictly needed but avoid confusion when comparing booleans\n  #elseif ($m.kind == \"ARRAY\")\n    #if ($params.containsKey($m.toString()))\n    `java.util.Arrays`.equals($m,\n        (that instanceof $className)\n            ? (($className) that).$m\n            : that.${m}()) ##\n    #else ## default value, so if |that| is also a $className then it has the same constant value\n    (that instanceof $className || `java.util.Arrays`.equals($m, that.${m}()))\n    #end\n  #else\n    ${m}.equals(that.${m}()) ##\n  #end\n#end\n\n  @`java.lang.Override`\n  public boolean equals($equalsParameterType o) {\n    if (o == this) {\n      return true;\n    }\n    if (o instanceof $annotationName) {\n\n  #if ($members.isEmpty())\n\n      return true;\n\n  #else\n\n      $annotationName that = ($annotationName) o;\n      return ##\n           #foreach ($m in $members)\n           #memberEqualsThatExpression ($m)##\n             #if ($foreach.hasNext)\n\n           && ##\n             #end\n           #end\n           ;\n  #end\n\n    }\n    return false;\n  }\n\n## hashCode\n\n## An expression that returns the hashCode of `this.something`.\n## It appears on the right-hand side of an ^ operator, so if that would cause precedence\n## problems the expression needs to be parenthesized.\n#macro (memberHashCodeExpression $m)\n  #if ($m.kind == \"LONG\")\n    (int) (($m >>> 32) ^ $m) ##\n  #elseif ($m.kind == \"FLOAT\")\n    Float.floatToIntBits($m) ##\n  #elseif ($m.kind == \"DOUBLE\")\n    (int) ((Double.doubleToLongBits($m) >>> 32) ^ Double.doubleToLongBits($m)) ##\n  #elseif ($m.kind == \"BOOLEAN\")\n    ($m ? 1231 : 1237) ##\n  #elseif ($m.kind.primitive)\n    $m ##\n  #elseif ($m.kind == \"ARRAY\")\n    `java.util.Arrays`.hashCode($m) ##\n  #else\n    ${m}.hashCode() ##\n  #end\n#end\n\n## The hashCode is the sum of two parts, an invariable part and a variable part. The invariable part\n## comes from defaulted members (ones that don't appear in the @AutoAnnotation method parameters)\n## whose values have hash codes that never change. (That doesn't include Class constants, for\n## example.) We precompute the invariable part, as an optimization but also in order to avoid\n## falling afoul of constant-overflow checks in the compiler.\n\n  @`java.lang.Override`\n  public int hashCode() {\n    return\n    ## If the invariable part is 0, we avoid outputting `return 0 + ...` just because it generates\n    ## unnecessary byte code. But if there are no members then we must say `return 0;` here.\n    ## We must write $members.isEmpty() because $members is a Map and Velocity interprets\n    ## $members.empty as meaning $members[\"empty\"] in that case.\n    #if ($invariableHashSum != 0 || $members.isEmpty())\n\n        $invariableHashSum\n        // $invariableHashSum is the contribution from default members $invariableHashes\n    #end\n    #foreach ($m in $members)\n      #if (!$invariableHashes.contains($m.toString()))\n\n        + ($m.nameHash ^ #memberHashCodeExpression($m))\n            // $m.nameHash is 127 * \"${m}\".hashCode()\n      #end\n    #end\n\n        ;\n\n  }\n\n## support functions\n\n#foreach ($w in $wrapperTypesUsedInCollections)\n  #set ($prim = $w.getField(\"TYPE\").get(\"\"))\n\n  private static ${prim}[] ${prim}ArrayFromCollection(`java.util.Collection`<${w.simpleName}> c) {\n    ${prim}[] a = new ${prim}[c.size()];\n    int i = 0;\n    for (${prim} x : c) {\n      a[i++] = x;\n    }\n    return a;\n  }\n#end\n\n#if ($appendQuotedStringArrayMethod)\n  #set ($appendQuotedStringMethod = \"true\")\n\n  private static void appendQuoted(StringBuilder sb, String[] strings) {\n    sb.append('[');\n    String sep = \"\";\n    for (String s : strings) {\n      sb.append(sep);\n      sep = \", \";\n      appendQuoted(sb, s);\n    }\n    sb.append(']');\n  }\n#end\n\n#if ($appendQuotedCharArrayMethod)\n  #set ($appendQuotedCharMethod = \"true\")\n\n  private static void appendQuoted(StringBuilder sb, char[] chars) {\n    sb.append('[');\n    String sep = \"\";\n    for (char c : chars) {\n      sb.append(sep);\n      sep = \", \";\n      appendQuoted(sb, c);\n    }\n    sb.append(']');\n  }\n#end\n\n#if ($appendQuotedStringMethod)\n  #set ($appendEscapedMethod = \"true\")\n\n  private static void appendQuoted(StringBuilder sb, String s) {\n    sb.append('\"');\n    for (int i = 0; i < s.length(); i++) {\n      appendEscaped(sb, s.charAt(i));\n    }\n    sb.append('\"');\n  }\n#end\n\n#if ($appendQuotedCharMethod)\n  #set ($appendEscapedMethod = \"true\")\n\n  private static void appendQuoted(StringBuilder sb, char c) {\n    sb.append('\\'');\n    appendEscaped(sb, c);\n    sb.append('\\'');\n  }\n#end\n\n#if ($appendEscapedMethod)\n  private static void appendEscaped(StringBuilder sb, char c) {\n    switch (c) {\n    case '\\\\':\n    case '\"':\n    case '\\'':\n      sb.append('\\\\').append(c);\n      break;\n    case '\\n':\n      sb.append(\"\\\\n\");\n      break;\n    case '\\r':\n      sb.append(\"\\\\r\");\n      break;\n    case '\\t':\n      sb.append(\"\\\\t\");\n      break;\n    default:\n      if (c < 0x20) {\n        sb.append('\\\\');\n        appendWithZeroPadding(sb, Integer.toOctalString(c), 3);\n      } else if (c < 0x7f || Character.isLetter(c)) {\n        sb.append(c);\n      } else {\n        sb.append(\"\\\\u\");\n        appendWithZeroPadding(sb, Integer.toHexString(c), 4);\n      }\n      break;\n    }\n  }\n\n  ## We use this rather than String.format because that doesn't exist on GWT.\n\n  private static void appendWithZeroPadding(StringBuilder sb, String s, int width) {\n    for (int i = width - s.length(); i > 0; i--) {\n      sb.append('0');\n    }\n    sb.append(s);\n  }\n#end\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/autobuilder.vm",
    "content": "## Copyright 2014 Google LLC\n##\n## Licensed under the Apache License, Version 2.0 (the \"License\");\n## you may not use this file except in compliance with the License.\n## You may obtain a copy of the License at\n##\n## http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n\n## Template for each generated AutoBuilder_Foo class.\n## This template uses the Apache Velocity Template Language (VTL).\n## The variables ($pkg, $props, and so on) are defined by the fields of AutoBuilderTemplateVars.\n##\n## Comments, like this one, begin with ##. The comment text extends up to and including the newline\n## character at the end of the line. So comments also serve to join a line to the next one.\n## Velocity deletes a newline after a directive (#if, #foreach, #end etc) so ## is not needed there.\n## That does mean that we sometimes need an extra blank line after such a directive.\n##\n## Post-processing will remove unwanted spaces and blank lines, but will not join two lines.\n## It will also replace classes spelled as (e.g.) `java.util.Arrays`, with the backquotes, to\n## use just Arrays if that class can be imported unambiguously, or java.util.Arrays if not.\n\n#if (!$pkg.empty)\npackage $pkg;\n#end\n\n## The following line will be replaced by the required imports during post-processing.\n`import`\n\n#if (!$generated.empty)\n@${generated}(\"com.google.auto.value.processor.AutoBuilderProcessor\")\n#else\n// Generated by com.google.auto.value.processor.AutoBuilderProcessor\n#end\n#set($autoBuilder = true)\n#parse(\"builder.vm\")\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/autobuilderannotation.vm",
    "content": "## Copyright 2022 Google LLC\n##\n## Licensed under the Apache License, Version 2.0 (the \"License\");\n## you may not use this file except in compliance with the License.\n## You may obtain a copy of the License at\n##\n## http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n\n## Template for each generated AutoBuilderAnnotation_Foo_Bar class.\n## This template uses the Apache Velocity Template Language (VTL).\n## The variables ($pkg, $props, and so on) are defined by the fields of\n## AutoBuilderAnnotationTemplateVars.\n##\n## Comments, like this one, begin with ##. The comment text extends up to and including the newline\n## character at the end of the line. So comments also serve to join a line to the next one.\n## Velocity deletes a newline after a directive (#if, #foreach, #end etc) so ## is not needed there.\n## That does mean that we sometimes need an extra blank line after such a directive.\n##\n## Post-processing will remove unwanted spaces and blank lines, but will not join two lines.\n## It will also replace classes spelled as (e.g.) `java.util.Arrays`, with the backquotes, to\n## use just Arrays if that class can be imported unambiguously, or java.util.Arrays if not.\n\n#if (!$pkg.empty)\npackage $pkg;\n#end\n\n## The following line will be replaced by the required imports during post-processing.\n`import`\n\n#if (!$generated.empty)\n@${generated}(\"com.google.auto.value.processor.AutoBuilderProcessor\")\n#else\n// Generated by com.google.auto.value.processor.AutoBuilderProcessor\n#end\nclass $className {\n  @`com.google.auto.value.AutoAnnotation`\n  static ${annotationType} newAnnotation(\n#foreach ($p in $props)\n      $p.type $p #if ($foreach.hasNext) , #end\n#end\n      ) {\n    return new AutoAnnotation_${className}_newAnnotation(\n#foreach ($p in $props)\n        $p #if ($foreach.hasNext) , #end\n#end\n        );\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/autooneof.vm",
    "content": "## Copyright 2018 Google LLC\n##\n## Licensed under the Apache License, Version 2.0 (the \"License\");\n## you may not use this file except in compliance with the License.\n## You may obtain a copy of the License at\n##\n## http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n\n## Template for each generated AutoOneOf_Foo class.\n## This template uses the Apache Velocity Template Language (VTL).\n## The variables ($pkg, $props, and so on) are defined by the fields of AutoOneOfTemplateVars.\n##\n## Comments, like this one, begin with ##. The comment text extends up to and including the newline\n## character at the end of the line. So comments also serve to join a line to the next one.\n## Velocity deletes a newline after a directive (#if, #foreach, #end etc) so ## is not needed there.\n## That does mean that we sometimes need an extra blank line after such a directive.\n##\n## Post-processing will remove unwanted spaces and blank lines, but will not join two lines.\n## It will also replace classes spelled as (e.g.) `java.util.Arrays`, with the backquotes, to\n## use just Arrays if that class can be imported unambiguously, or java.util.Arrays if not.\n\n## Get #equalsThatExpression($p) and #hashCodeExpression($p).\n#parse(\"equalshashcode.vm\")\n\n#if (!$pkg.empty)\npackage $pkg;\n#end\n\n## The following line will be replaced by the required imports during post-processing.\n`import`\n\n#if ($generated.empty)\n// Generated by com.google.auto.value.processor.AutoOneOfProcessor\n#else\n@${generated}(\"com.google.auto.value.processor.AutoOneOfProcessor\")\n#end\nfinal class $generatedClass {\n  private ${generatedClass}() {} // There are no instances of this type.\n\n## Factory methods.\n#foreach ($p in $props)\n\n  #if ($p.type == \"void\")\n    #if ($wildcardTypes == \"\")\n\n  static $origClass $p() {\n    return Impl_${p}.INSTANCE;\n  }\n\n    #else\n\n  @SuppressWarnings(\"unchecked\") // type parameters are unused in void instances\n  static $formalTypes $origClass$actualTypes $p() {\n    return ($origClass$actualTypes) Impl_${p}.INSTANCE;\n  }\n\n    #end\n\n  #else\n\n  ## If the @AutoOneOf type is TaskResult<V extends Serializable>, then we might have here:\n  ## static <V extends Serializable> TaskResult<V> value(V value) {\n  ##   return new Impl_value<V>(value);\n  ## }\n  ## The parameter type might be something else (Throwable for example), but we will still\n  ## want <V extends Serializable> TaskResult<V>.\n\n  static $formalTypes $origClass$actualTypes $p($p.type $p) {\n\n    #if (!$p.kind.primitive)\n\n    `java.util.Objects`.requireNonNull($p);\n\n    #end\n\n    return new Impl_$p$actualTypes($p);\n  }\n\n  #end\n\n#end\n\n  #foreach ($a in $annotations)\n\n  $a\n\n  #end\n\n#if (!$props.empty)\n  // Parent class that each implementation will inherit from.\n  private abstract static class Parent_$formalTypes extends $origClass$actualTypes {\n\n  $serialVersionUID\n\n  #foreach ($p in $props)\n\n    @`java.lang.Override`\n    $p.access $p.type ${p.getter}() {\n      throw new UnsupportedOperationException(${kindGetter}().toString());\n    }\n\n  #end\n\n  }\n#end\n\n#foreach ($p in $props)\n\n\n  #foreach ($a in $annotations)\n\n  $a\n\n  #end\n\n  // Implementation when the contained property is \"${p}\".\n  private static final class Impl_$p$formalTypes extends Parent_$actualTypes {\n\n  $serialVersionUID\n\n  #if ($p.type == \"void\")\n\n    // There is only one instance of this class.\n    static final Impl_$p$wildcardTypes INSTANCE = new ##\n      #if ($wildcardTypes == \"\") Impl_$p() #else Impl_$p<>() #end;\n\n    private Impl_$p() {}\n\n    @`java.lang.Override`\n    public void ${p.getter}() {}\n\n    #if ($serializable)\n\n    private `java.lang.Object` readResolve() {\n      return INSTANCE;\n    }\n\n    #end\n\n    #if ($toString)\n\n    @`java.lang.Override`\n    public `java.lang.String` toString() {\n      return \"${simpleClassName}{$p.name}\";\n    }\n\n    #end\n\n    ## The implementations of equals and hashCode are equivalent to the ones\n    ## we inherit from Object. We only need to define them if they're redeclared\n    ## as abstract in an ancestor class. But currently we define them always.\n\n    #if ($equals)\n\n    @`java.lang.Override`\n    public boolean equals($equalsParameterType x) {\n      return x == this;\n    }\n\n    #end\n\n    #if ($hashCode)\n\n    @`java.lang.Override`\n    public int hashCode() {\n      return `java.lang.System`.identityHashCode(this);\n    }\n\n    #end\n\n  #else\n\n    private final $p.type $p;\n\n    Impl_$p($p.type $p) {\n      this.$p = $p;\n    }\n\n    @`java.lang.Override`\n    public $p.type ${p.getter}() {\n      return $p;\n    }\n\n    #if ($toString)\n\n    @`java.lang.Override`\n    public `java.lang.String` toString() {\n      return \"${simpleClassName}{$p.name=\" ##\n          + #if ($p.kind == \"ARRAY\") `java.util.Arrays`.toString(this.$p) #else this.$p #end\n          + \"}\";\n    }\n\n    #end\n\n    #if ($equals)\n\n    @`java.lang.Override`\n    public boolean equals($equalsParameterType x) {\n      if (x instanceof $origClass) {\n        $origClass$wildcardTypes that = ($origClass$wildcardTypes) x;\n        return this.${kindGetter}() == that.${kindGetter}()\n            && #equalsThatExpression($p \"Impl_$p\");\n      } else {\n        return false;\n      }\n    }\n\n    #end\n\n    #if ($hashCode)\n\n    @`java.lang.Override`\n    public int hashCode() {\n      return #hashCodeExpression($p);\n    }\n\n    #end\n\n  #end\n\n    @`java.lang.Override`\n    public $kindType ${kindGetter}() {\n      return ${kindType}.$propertyToKind[$p.name];\n    }\n\n  }\n\n#end\n\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/autovalue.vm",
    "content": "## Copyright 2014 Google LLC\n##\n## Licensed under the Apache License, Version 2.0 (the \"License\");\n## you may not use this file except in compliance with the License.\n## You may obtain a copy of the License at\n##\n## http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n\n## Template for each generated AutoValue_Foo class.\n## This template uses the Apache Velocity Template Language (VTL).\n## The variables ($pkg, $props, and so on) are defined by the fields of AutoValueTemplateVars.\n##\n## Comments, like this one, begin with ##. The comment text extends up to and including the newline\n## character at the end of the line. So comments also serve to join a line to the next one.\n## Velocity deletes a newline after a directive (#if, #foreach, #end etc) so ## is not needed there.\n## That does mean that we sometimes need an extra blank line after such a directive.\n##\n## Post-processing will remove unwanted spaces and blank lines, but will not join two lines.\n## It will also replace classes spelled as (e.g.) `java.util.Arrays`, with the backquotes, to\n## use just Arrays if that class can be imported unambiguously, or java.util.Arrays if not.\n\n## Get #equalsThatExpression($p) and #hashCodeExpression($p).\n#parse(\"equalshashcode.vm\")\n\n#if (!$pkg.empty)\npackage $pkg;\n#end\n\n## The following line will be replaced by the required imports during post-processing.\n`import`\n\n#if ($gwtCompatibleAnnotation)$gwtCompatibleAnnotation\n#end\n#foreach ($a in $annotations)\n$a\n#end\n#if (!$generated.empty)\n@${generated}(\"com.google.auto.value.processor.AutoValueProcessor\")\n#else\n// Generated by com.google.auto.value.processor.AutoValueProcessor\n#end\n${modifiers}class $subclass$formalTypes extends $origClass$actualTypes {\n\n## Fields\n\n#foreach ($p in $props)\n  #foreach ($a in ${p.fieldAnnotations})\n\n  ${a}##\n  #end\n\n  private final $p.type $p;\n#end\n\n## Constructor\n\n#if ($isFinal && $builderTypeName != \"\")\n  private ##\n#end\n  $subclass(\n#foreach ($p in $props)\n\n      ${p.nullableAnnotation}$p.type $p #if ($foreach.hasNext) , #end\n#end ) {\n#foreach ($p in $props)\n  #if (!$p.kind.primitive && !$p.nullable && ($builderTypeName == \"\" || !$isFinal))\n    ## We don't need a null check if the type is primitive or @Nullable. We also don't need it\n    ## if there is a builder, since the build() method will check for us. However, if there is a\n    ## builder but there are also extensions (!$isFinal) then we can't omit the null check because\n    ## the constructor is called from the extension code.\n\n    #if ($identifiers)\n    if ($p == null) {\n      throw new NullPointerException(\"Null $p.name\");\n    }\n    #else\n    `java.util.Objects`.requireNonNull($p);\n    #end\n\n  #end\n\n    this.$p = $p;\n#end\n  }\n\n## Property getters\n\n#foreach ($p in $props)\n\n  #foreach ($a in ${p.methodAnnotations})\n\n  ${a}##\n  #end\n\n  @`java.lang.Override`\n  ${p.access}${p.type} ${p.getter}() {\n    return $p;\n  }\n\n#end\n\n#if ($toString)\n\n  @`java.lang.Override`\n  public `java.lang.String` toString() {\n    return \"#if ($identifiers)$simpleClassName#end{\"\n\n  #foreach ($p in $props)\n\n        #if ($identifiers)+ \"$p.name=\" ##\n        #end+ #if ($p.kind == \"ARRAY\") `java.util.Arrays`.toString($p) #else $p #end\n        #if ($foreach.hasNext) + \", \" #end\n\n  #end\n\n        + \"}\";\n  }\n\n#end\n\n#if ($equals)\n\n  @`java.lang.Override`\n  public boolean equals($equalsParameterType o) {\n    if (o == this) {\n      return true;\n    }\n    if (o instanceof $origClass) {\n\n  #if ($props.empty)\n\n      return true;\n\n  #else\n\n      $origClass$wildcardTypes that = ($origClass$wildcardTypes) o;\n      return ##\n          #foreach ($p in $props)\n          #equalsThatExpression ($p $subclass)##\n            #if ($foreach.hasNext)\n\n          && ##\n            #end\n          #end\n          ;\n  #end\n\n    }\n    return false;\n  }\n\n#end\n\n#if ($hashCode)\n\n  @`java.lang.Override`\n  public int hashCode() {\n    int h$ = 1;\n\n  #foreach ($p in $props)\n\n    h$ *= 1000003;\n    h$ ^= #hashCodeExpression($p);\n\n  #end\n\n    return h$;\n  }\n#end\n\n  $serialVersionUID\n\n#if ($builderTypeName != \"\")\n\n  #foreach ($m in $toBuilderMethods)\n\n  @`java.lang.Override`\n  ${m.access}${builderTypeName}${builderActualTypes} ${m.name}() {\n    return new ${finalSubclass}.Builder${builderActualTypes}(this);\n  }\n\n  #end\n\n  ## BUILDER CLASS\n\n  #set($autoBuilder = false)\n  #parse(\"builder.vm\")\n#end\n\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/builder.vm",
    "content": "## Copyright 2014 Google LLC\n##\n## Licensed under the Apache License, Version 2.0 (the \"License\");\n## you may not use this file except in compliance with the License.\n## You may obtain a copy of the License at\n##\n## http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n##\n##\n##\n## Template for AutoValue and AutoBuilder builders.\n## This template uses the Apache Velocity Template Language (VTL).\n## The variables ($isFinal, $props, and so on) are defined by the fields of AutoValueOrBuilderTemplateVars.\n##\n## Comments, like this one, begin with ##. The comment text extends up to and including the newline\n## character at the end of the line. So comments also serve to join a line to the next one.\n## Velocity deletes a newline after a directive (#if, #foreach, #end etc) so ## is not needed there.\n## That does mean that we sometimes need an extra blank line after such a directive.\n##\n## Post-processing will remove unwanted spaces and blank lines, but will not join two lines.\n## It will also replace classes spelled as (e.g.) `java.util.Arrays`, with the backquotes, to\n## use just Arrays if that class can be imported unambiguously, or java.util.Arrays if not.\n##\n#foreach ($a in $builderAnnotations)\n$a\n#end\n${builderClassModifiers}class ${builderName}${builderFormalTypes} ##\n#if ($builderIsInterface) implements #else extends #end\n    ${builderTypeName}${builderActualTypes} {\n\n#foreach ($p in $props)\n  #if ($builderPropertyBuilders[$p.name])\n    ## If you have ImmutableList.Builder<String> stringsBuilder() then we define two fields:\n    ## private ImmutableList.Builder<String> stringsBuilder$;\n    ## private ImmutableList<String> strings;\n\n  private ${builderPropertyBuilders[$p.name].nullableBuilderType} ##\n      ${builderPropertyBuilders[$p.name].name};\n\n  #end\n\n  private $p.builderFieldType $p $p.builderInitializer;\n\n#end\n\n#foreach ($decl in $builderRequiredProperties.fieldDeclarations)\n  $decl\n#end\n\n  ${builderName}() {\n  }\n\n#if ($toBuilderConstructor)\n\n  ${builderName}($builtType source) {\n\n  #foreach ($p in $props)\n\n    this.$p = source.${p.getter}();\n\n  #end\n\n  #foreach ($init in $builderRequiredProperties.initToAllSet)\n    $init\n  #end\n\n  }\n\n#end\n\n#foreach ($p in $props)\n\n  ## The following is either null or an instance of PropertyBuilderClassifier.PropertyBuilder\n  #set ($propertyBuilder = $builderPropertyBuilders[$p.name])\n\n  ## Setter and/or property builder\n\n  #foreach ($setter in $builderSetters[$p.name])\n\n  @`java.lang.Override`\n  ${setter.access}${builderTypeName}${builderActualTypes} ##\n      ${setter.name}(${setter.nullableAnnotation}$setter.parameterType $p) {\n\n    ## Omit null check for primitive, or @Nullable, or if we are going to be calling a copy method\n    ## such as Optional.of, which will have its own null check if appropriate.\n    #if (!$setter.primitiveParameter && !$p.nullable && ${setter.copy($p)} == $p)\n\n      #if ($identifiers)\n    if ($p == null) {\n      throw new NullPointerException(\"Null $p.name\");\n    }\n      #else\n    `java.util.Objects`.requireNonNull($p);\n      #end\n\n    #end\n\n    #if ($propertyBuilder)\n\n    if (${propertyBuilder.name} != null) {\n      throw new IllegalStateException(#if ($identifiers)\"Cannot set $p after calling ${p.name}Builder()\"#end);\n    }\n\n    #end\n\n    this.$p = ${setter.copy($p)};\n\n    $builderRequiredProperties.markAsSet($p)\n\n    return this;\n  }\n\n  #end\n\n  #if ($propertyBuilder)\n\n  @`java.lang.Override`\n  ${propertyBuilder.access}$propertyBuilder.builderType ##\n      ${propertyBuilder.methodName}($propertyBuilder.propertyBuilderMethodParameters) {\n    if (${propertyBuilder.name} == null) {\n\n      ## This is the first time someone has asked for the builder. If the property it sets already\n      ## has a value (because it came from the copy constructor, or because there is also a setter\n      ## for this property) then we copy that value into the builder.\n      ## Otherwise the builder starts out empty.\n      ## If we have neither a setter nor a toBuilder() method, then the builder always starts\n      ## off empty.\n\n      #if ($builderSetters[$p.name].empty && !$toBuilderConstructor)\n\n      ${propertyBuilder.name} = ${propertyBuilder.initializer};\n      $builderRequiredProperties.markAsSet($p)\n\n      #else\n\n      if ($p == null) {\n        ${propertyBuilder.name} = ${propertyBuilder.initializer};\n        $builderRequiredProperties.markAsSet($p)\n      } else {\n\n        #if (${propertyBuilder.builtToBuilder})\n\n        ${propertyBuilder.name} = ${p}.${propertyBuilder.builtToBuilder}();\n\n        #else\n\n        ${propertyBuilder.name} = ${propertyBuilder.initializer};\n        ${propertyBuilder.name}.${propertyBuilder.copyAll}($p);\n\n        #end\n\n        $p = null;\n      }\n\n      #end\n\n    } #if (!$propertyBuilder.propertyBuilderMethodParameters.empty) else {\n        ## This check only happens if the property-builder method has a parameter.\n        ## We don't know if the existing builder was created with the same parameter,\n        ## so we throw to avoid possibly giving you a builder that is different from\n        ## the one you asked for.\n\n      throw new IllegalStateException(\"Property builder for $p.name is already defined\");\n    }\n      #end\n\n    return $propertyBuilder.name;\n  }\n\n  #end\n\n  ## Getter\n\n  #set ($builderGetter = $builderGetters[$p.name])\n  #if ($builderGetter)\n\n  @`java.lang.Override`\n  ${p.nullableAnnotation}${builderGetter.access}$builderGetter.type ${builderGetter.name}() {\n    #set ($noValueToGetCondition = $builderRequiredProperties.noValueToGet($p))\n\n    #if ($builderGetters[$p.name].optional)\n      #if ($noValueToGetCondition)\n    if ($noValueToGetCondition) {\n      return $builderGetter.optional.empty;\n    }\n      #else\n    if ($p == null) {\n      return $builderGetter.optional.empty;\n    }\n      #end\n    return ${builderGetter.optional.rawType}.of($p);\n\n    #else\n      #if ($noValueToGetCondition)\n    if ($noValueToGetCondition) {\n      throw new IllegalStateException(#if ($identifiers)\"Property \\\"$p.name\\\" has not been set\"#end);\n    }\n      #end\n\n      #if ($propertyBuilder)\n\n    if (${propertyBuilder.name} != null) {\n      return ${propertyBuilder.name}.${propertyBuilder.build}();\n    }\n    if ($p == null) {\n      ${propertyBuilder.beforeInitDefault}\n      $p = ${propertyBuilder.initDefault};\n    }\n\n      #end\n\n    return $p;\n\n    #end\n\n  }\n\n  #end\n#end\n\n## build() method\n\n  @`java.lang.Override`\n  ${buildMethod.get().access}${builtType} ${buildMethod.get().name}() ${buildMethod.get().throws} {\n\n#foreach ($p in $props)\n  #set ($propertyBuilder = $builderPropertyBuilders[$p.name])\n  #if ($propertyBuilder)\n\n    if (${propertyBuilder.name} != null) {\n      this.$p = ${propertyBuilder.name}.${propertyBuilder.build}();\n    } else if (this.$p == null) {\n      ${propertyBuilder.beforeInitDefault}\n      this.$p = ${propertyBuilder.initDefault};\n    }\n\n  #end\n#end\n\n#if (!$builderRequiredProperties.requiredProperties.empty)\n    if ($builderRequiredProperties.anyMissing) {\n\n  #if ($identifiers)  ## build a friendly message showing all missing properties\n    #if ($builderRequiredProperties.requiredProperties.size() == 1)\n\n      `java.lang.String` missing = \" $builderRequiredProperties.requiredProperties.iterator().next()\";\n\n    #else\n\n      `java.lang.StringBuilder` missing = new `java.lang.StringBuilder`();\n\n      #foreach ($p in $builderRequiredProperties.requiredProperties)\n      if ($builderRequiredProperties.missingRequiredProperty($p)) {\n        missing.append(\" $p.name\");\n      }\n      #end\n    #end\n\n      throw new IllegalStateException(\"Missing required properties:\" + missing);\n\n  #else  ## just throw an exception if anything is missing\n\n      throw new IllegalStateException();\n\n  #end\n\n    }\n\n#end\n\n    #if ($builtType != \"void\") return #end ${build}(\n#foreach ($p in $props)\n\n        this.$p #if ($foreach.hasNext) , #end\n#end\n        $builderRequiredProperties.defaultedBitmaskParameters );\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/equalshashcode.vm",
    "content": "## Copyright 2018 Google LLC\n##\n## Licensed under the Apache License, Version 2.0 (the \"License\");\n## you may not use this file except in compliance with the License.\n## You may obtain a copy of the License at\n##\n## http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n\n## Shared definitions for @AutoFoo templates. This is included in those templates using\n## the #parse directive.\n##\n## This template uses the Apache Velocity Template Language (VTL).\n## The variables ($pkg, $props, and so on) are defined by the fields of AutoValueTemplateVars.\n##\n## Comments, like this one, begin with ##. The comment text extends up to and including the newline\n## character at the end of the line. So comments also serve to join a line to the next one.\n## Velocity deletes a newline after a directive (#if, #foreach, #end etc) so ## is not needed there.\n## That does mean that we sometimes need an extra blank line after such a directive.\n##\n## Post-processing will remove unwanted spaces and blank lines, but will not join two lines.\n## It will also replace classes spelled as (e.g.) `java.util.Arrays`, with the backquotes, to\n## use just Arrays if that class can be imported unambiguously, or java.util.Arrays if not.\n\n## In the following two macros, $p is an object of type AutoValueProcessor.Property\n## or AutoOneOfProcessor.Property. $p.kind means the getKind() method of those classes,\n## and likewise for $p.getter and $p.nullable (isNullable()).\n\n## Expands to an expression appropriate for comparing the $p property in `this` against\n## the $p property in `that`. If we're generating code for `AutoValue_Baz` then\n## `that` is of type `Baz`.\n## As an example, if $p is the `foo` property and $p.kind is FLOAT,\n## this becomes `Float.floatToIntBits(this.foo) == Float.floatToIntBits(that.foo())`\n## or `...that.getFoo()...`.\n## The expression should be surrounded by parentheses if otherwise there might be precedence\n## problems when it is followed by &&.\n## A reminder that trailing ## here serves to delete the newline, which we don't want in the output.\n#macro (equalsThatExpression $p $subclass)\n  #if ($p.kind == \"FLOAT\")\n    `java.lang.Float`.floatToIntBits(this.$p) == `java.lang.Float`.floatToIntBits(that.${p.getter}()) ##\n  #elseif ($p.kind == \"DOUBLE\")\n    `java.lang.Double`.doubleToLongBits(this.$p) == `java.lang.Double`.doubleToLongBits(that.${p.getter}()) ##\n  #elseif ($p.kind.primitive)\n    this.$p == that.${p.getter}() ##\n  #elseif ($p.kind == \"ARRAY\")\n    `java.util.Arrays`.equals(this.$p, ##\n        (that instanceof $subclass) ? (($subclass$wildcardTypes) that).$p : that.${p.getter}()) ##\n  #elseif ($p.nullable)\n    (this.$p == null ? that.${p.getter}() == null : this.${p}.equals(that.${p.getter}())) ##\n  #else\n    this.${p}.equals(that.${p.getter}()) ##\n  #end\n#end\n\n## Expands to an expression to compute the hashCode of the $p property.\n## For example, if $p is the `foo` property and $p.kind is FLOAT,\n## this becomes `Float.floatToIntBits(this.foo)`.\n## A reminder that trailing ## here serves to delete the newline, which we don't want in the output.\n#macro (hashCodeExpression $p)\n  #if ($p.kind == \"LONG\")\n    (int) (($p >>> 32) ^ $p) ##\n  #elseif ($p.kind == \"FLOAT\")\n    `java.lang.Float`.floatToIntBits($p) ##\n  #elseif ($p.kind == \"DOUBLE\")\n    (int) ((`java.lang.Double`.doubleToLongBits($p) >>> 32) ^ `java.lang.Double`.doubleToLongBits($p)) ##\n  #elseif ($p.kind == \"BOOLEAN\")\n    $p ? 1231 : 1237 ##\n  #elseif ($p.kind.primitive)\n    $p ##\n  #elseif ($p.kind == \"ARRAY\")\n    `java.util.Arrays`.hashCode($p) ##\n  #elseif ($p.nullable)\n    ($p == null) ? 0 : ${p}.hashCode() ##\n  #else\n    ${p}.hashCode() ##\n  #end\n#end\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/gwtserializer.vm",
    "content": "## Copyright 2014 Google LLC\n##\n## Licensed under the Apache License, Version 2.0 (the \"License\");\n## you may not use this file except in compliance with the License.\n## You may obtain a copy of the License at\n##\n## http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n\n## Template for each generated AutoValue_Foo_CustomFieldSerializer class.\n## This template uses the Apache Velocity Template Language (VTL).\n## The variables ($pkg, $props, and so on) are defined by the fields of\n## GwtSerialization.GwtTemplateVars.\n##\n## Comments, like this one, begin with ##. The comment text extends up to and including the newline\n## character at the end of the line. So comments also serve to join a line to the next one.\n## Velocity deletes a newline after a directive (#if, #foreach, #end etc) so ## is not needed there.\n## That does mean that we sometimes need an extra blank line after such a directive.\n##\n## A post-processing step will remove unwanted spaces and blank lines, but will not join two lines.\n## TODO(emcmanus): perform the post-processing.\n#if (!$pkg.empty)\npackage $pkg;\n#end\n\n## The following line will be replaced by the required imports during post-processing.\n`import`\n\n#if (!$generated.empty)\n@${generated}(\"com.google.auto.value.processor.AutoValueProcessor\")\n#else\n// Generated by com.google.auto.value.processor.AutoValueProcessor\n#end\npublic final class $serializerClass$formalTypes\n    extends `com.google.gwt.user.client.rpc.CustomFieldSerializer`<$subclass$actualTypes> {\n\n  public static $formalTypes $subclass$actualTypes instantiate(\n      `com.google.gwt.user.client.rpc.SerializationStreamReader` streamReader)\n      throws `com.google.gwt.user.client.rpc.SerializationException` {\n#foreach ($p in $props)\n    #if ($p.castingUnchecked)\n    @SuppressWarnings(\"unchecked\")\n    #end\n    $p.type $p = ${p.gwtCast}streamReader.read${p.gwtType}();\n#end\n#if ($useBuilder)\n\n    ${subclass}.Builder${actualTypes} builder$ = new ${subclass}.Builder${actualTypes}();\n  #foreach ($p in $props)\n\n    #if ($builderSetters[$p.name].empty)\n      #set ($propertyBuilder = $builderPropertyBuilders[$p.name])\n\n    builder$.${propertyBuilder.propertyBuilderMethod}.${propertyBuilder.copyAll}($p);\n\n    #else\n\n    builder$.${builderSetters[$p.name].iterator().next().name}($p);\n    #end\n  #end\n\n    return (${subclass}${actualTypes}) builder$.build();\n#else\n\n    return new ${subclass}$actualTypes(\n        #foreach ($p in $props) $p #if ($foreach.hasNext) , #end #end);\n\n#end\n  }\n\n  public static $formalTypes void serialize(\n      `com.google.gwt.user.client.rpc.SerializationStreamWriter` streamWriter,\n      $subclass$actualTypes instance) throws `com.google.gwt.user.client.rpc.SerializationException` {\n#foreach ($p in $props)\n    streamWriter.write${p.gwtType}(instance.${p.getter}());\n#end\n  }\n\n  public static $formalTypes void deserialize(\n      @SuppressWarnings(\"unused\") `com.google.gwt.user.client.rpc.SerializationStreamReader` streamReader,\n      @SuppressWarnings(\"unused\") $subclass$actualTypes instance) {\n    // instantiate already did all the work.\n  }\n\n  // This dummy field is a hash of the fields in ${subclass}. It will change if they do, including\n  // if their order changes. This is because GWT identity for a class that has a serializer is\n  // based on the fields of the serializer rather than the class itself.\n  @SuppressWarnings(\"unused\")\n  private int dummy_$classHashString;\n\n  @`java.lang.Override`\n  public void deserializeInstance(\n      `com.google.gwt.user.client.rpc.SerializationStreamReader` streamReader,\n      $subclass$actualTypes instance) {\n    deserialize(streamReader, instance);\n  }\n\n  @`java.lang.Override`\n  public boolean hasCustomInstantiateInstance() {\n    return true;\n  }\n\n  @`java.lang.Override`\n  public $subclass$actualTypes instantiateInstance(\n      `com.google.gwt.user.client.rpc.SerializationStreamReader` streamReader)\n      throws `com.google.gwt.user.client.rpc.SerializationException` {\n    return instantiate(streamReader);\n  }\n\n  @`java.lang.Override`\n  public void serializeInstance(\n      `com.google.gwt.user.client.rpc.SerializationStreamWriter` streamWriter,\n      $subclass$actualTypes instance)\n      throws `com.google.gwt.user.client.rpc.SerializationException` {\n    serialize(streamWriter, instance);\n  }\n}\n"
  },
  {
    "path": "value/src/main/java/com/google/auto/value/processor/package-info.java",
    "content": "/*\n * Copyright 2013 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n/**\n * This package contains the annotation processor that implements the {@link\n * com.google.auto.value.AutoValue} API.\n */\npackage com.google.auto.value.processor;\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/extension/memoized/MemoizedMethodSubject.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.auto.value.extension.memoized;\n\nimport static com.google.testing.compile.CompilationSubject.assertThat;\nimport static com.google.testing.compile.Compiler.javac;\n\nimport com.google.auto.value.extension.memoized.processor.MemoizeExtension;\nimport com.google.auto.value.processor.AutoValueProcessor;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.truth.FailureMetadata;\nimport com.google.common.truth.Subject;\nimport com.google.testing.compile.Compilation;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\n\nfinal class MemoizedMethodSubject extends Subject {\n  private final String actual;\n\n  MemoizedMethodSubject(FailureMetadata failureMetadata, String actual) {\n    super(failureMetadata, actual);\n    this.actual = actual;\n  }\n\n  void hasError(String error) {\n    JavaFileObject file =\n        JavaFileObjects.forSourceLines(\n            \"Value\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.auto.value.extension.memoized.Memoized;\",\n            \"\",\n            \"@AutoValue abstract class Value {\",\n            \"  abstract String string();\",\n            actual,\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(ImmutableList.of(new MemoizeExtension())))\n            .compile(file);\n    assertThat(compilation).hadErrorContaining(error).inFile(file).onLineContaining(actual);\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/extension/memoized/MemoizedMethodSubjectFactory.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.auto.value.extension.memoized;\n\nimport static com.google.common.truth.Truth.assertAbout;\n\nimport com.google.common.truth.FailureMetadata;\nimport com.google.common.truth.Subject;\n\nfinal class MemoizedMethodSubjectFactory implements Subject.Factory<MemoizedMethodSubject, String> {\n\n  static MemoizedMethodSubjectFactory memoizeMethod() {\n    return new MemoizedMethodSubjectFactory();\n  }\n\n  static MemoizedMethodSubject assertThatMemoizeMethod(String method) {\n    return assertAbout(memoizeMethod()).that(method);\n  }\n\n  @Override\n  public MemoizedMethodSubject createSubject(FailureMetadata failureMetadata, String that) {\n    return new MemoizedMethodSubject(failureMetadata, that);\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/extension/memoized/MemoizedTest.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.memoized;\n\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static com.google.common.truth.Truth.assertThat;\nimport static java.util.Arrays.stream;\nimport static org.junit.Assert.fail;\n\nimport com.google.auto.value.AutoValue;\nimport com.google.auto.value.AutoValue.CopyAnnotations;\nimport com.google.auto.value.extension.memoized.MemoizedTest.HashCodeEqualsOptimization.EqualsCounter;\nimport com.google.common.collect.ImmutableList;\nimport com.google.errorprone.annotations.Immutable;\nimport com.google.errorprone.annotations.ImmutableTypeParameter;\nimport java.lang.reflect.AnnotatedType;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Parameter;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic class MemoizedTest {\n\n  private Value value;\n  private ListValue<Integer, String> listValue;\n\n  @AutoValue\n  abstract static class ValueWithKeywordName {\n    abstract boolean getNative();\n\n    abstract boolean getNative0();\n\n    abstract String getNotKeyword();\n\n    @Memoized\n    boolean getMemoizedNative() {\n      return getNative();\n    }\n\n    @Memoized\n    boolean getMemoizedNative0() {\n      return getNative0();\n    }\n  }\n\n  @AutoValue\n  @CopyAnnotations\n  @javax.annotation.Nullable\n  abstract static class ValueWithCopyAnnotations {\n    abstract String getNative();\n\n    @Memoized\n    @javax.annotation.Nullable\n    public String getMemoizedNative() {\n      return getNative();\n    }\n  }\n\n  @AutoValue\n  @CopyAnnotations(exclude = javax.annotation.Nullable.class)\n  @javax.annotation.Nullable\n  abstract static class ValueWithExcludedCopyAnnotations {\n    abstract String getNative();\n\n    @Memoized\n    @CopyAnnotations(exclude = javax.annotation.Nullable.class)\n    @javax.annotation.Nullable\n    public String getMemoizedNative() {\n      return getNative();\n    }\n  }\n\n  @AutoValue\n  @javax.annotation.Nullable\n  abstract static class ValueWithoutCopyAnnotations {\n    abstract String getNative();\n\n    @Memoized\n    @javax.annotation.Nullable\n    public String getMemoizedNative() {\n      return getNative();\n    }\n  }\n\n  @AutoValue\n  abstract static class Value {\n    private int primitiveCount;\n    private int notNullableCount;\n    private int nullableCount;\n    private int returnsNullCount;\n    private int nullableWithTypeAnnotationCount;\n    private int returnsNullWithTypeAnnotationCount;\n    private int notNullableButReturnsNullCount;\n    private int throwsExceptionCount;\n\n    @javax.annotation.Nullable\n    abstract String string();\n\n    abstract @org.checkerframework.checker.nullness.qual.Nullable String stringWithTypeAnnotation();\n\n    abstract HashCodeAndToStringCounter counter();\n\n    @Memoized\n    int primitive() {\n      return ++primitiveCount;\n    }\n\n    @Memoized\n    String notNullable() {\n      notNullableCount++;\n      return \"derived \" + string() + \" \" + notNullableCount;\n    }\n\n    @Memoized\n    @javax.annotation.Nullable\n    String nullable() {\n      nullableCount++;\n      return \"nullable derived \" + string() + \" \" + nullableCount;\n    }\n\n    @Memoized\n    @javax.annotation.Nullable\n    String returnsNull() {\n      returnsNullCount++;\n      return null;\n    }\n\n    @Memoized\n    @org.checkerframework.checker.nullness.qual.Nullable\n    String nullableWithTypeAnnotation() {\n      nullableWithTypeAnnotationCount++;\n      return \"nullable derived \"\n          + stringWithTypeAnnotation()\n          + \" \"\n          + nullableWithTypeAnnotationCount;\n    }\n\n    @Memoized\n    @org.checkerframework.checker.nullness.qual.Nullable\n    String returnsNullWithTypeAnnotation() {\n      returnsNullWithTypeAnnotationCount++;\n      return null;\n    }\n\n    @Memoized\n    String notNullableButReturnsNull() {\n      notNullableButReturnsNullCount++;\n      return null;\n    }\n\n    @Memoized\n    String throwsException() throws SomeCheckedException {\n      throwsExceptionCount++;\n      throw new SomeCheckedException();\n    }\n\n    @Override\n    @Memoized\n    public abstract int hashCode();\n\n    @Override\n    @Memoized\n    public abstract String toString();\n  }\n\n  static final class SomeCheckedException extends Exception {}\n\n  @AutoValue\n  abstract static class ListValue<T extends Number, K> {\n\n    abstract T value();\n\n    abstract K otherValue();\n\n    @Memoized\n    ImmutableList<T> myTypedList() {\n      return ImmutableList.of(value());\n    }\n  }\n\n  static class HashCodeAndToStringCounter {\n    int hashCodeCount;\n    int toStringCount;\n\n    @Override\n    public int hashCode() {\n      return ++hashCodeCount;\n    }\n\n    @Override\n    public String toString() {\n      return \"a string\" + ++toStringCount;\n    }\n  }\n\n  @AutoValue\n  abstract static class HashCodeEqualsOptimization {\n    int overrideHashCode;\n    int hashCodeCount;\n\n    abstract EqualsCounter equalsCounter();\n\n    @Memoized\n    @Override\n    public int hashCode() {\n      hashCodeCount++;\n      return overrideHashCode;\n    }\n\n    static class EqualsCounter {\n      int equalsCount;\n\n      @Override\n      public int hashCode() {\n        return 0;\n      }\n\n      @Override\n      public boolean equals(Object obj) {\n        equalsCount++;\n        return true;\n      }\n    }\n  }\n\n  @AutoValue\n  abstract static class HashCodeEqualsOptimizationOffWhenEqualsIsFinal {\n    int hashCodeCount;\n\n    @Override\n    @Memoized\n    public int hashCode() {\n      hashCodeCount++;\n      return 1;\n    }\n\n    @Override\n    public final boolean equals(Object that) {\n      return that instanceof HashCodeEqualsOptimizationOffWhenEqualsIsFinal;\n    }\n  }\n\n  @Before\n  public void setUp() {\n    value =\n        new AutoValue_MemoizedTest_Value(\n            \"string\", \"stringWithTypeAnnotation\", new HashCodeAndToStringCounter());\n    listValue = new AutoValue_MemoizedTest_ListValue<Integer, String>(0, \"hello\");\n  }\n\n  @Test\n  public void listValueList() {\n    assertThat(listValue.myTypedList()).containsExactly(listValue.value());\n  }\n\n  @Test\n  public void listValueString() {\n    assertThat(listValue.otherValue()).isEqualTo(\"hello\");\n  }\n\n  @Test\n  public void primitive() {\n    assertThat(value.primitive()).isEqualTo(1);\n    assertThat(value.primitive()).isEqualTo(1);\n    assertThat(value.primitiveCount).isEqualTo(1);\n  }\n\n  @Test\n  public void notNullable() {\n    assertThat(value.notNullable()).isEqualTo(\"derived string 1\");\n    assertThat(value.notNullable()).isSameInstanceAs(value.notNullable());\n    assertThat(value.notNullableCount).isEqualTo(1);\n  }\n\n  @Test\n  public void nullable() {\n    assertThat(value.nullable()).isEqualTo(\"nullable derived string 1\");\n    assertThat(value.nullable()).isSameInstanceAs(value.nullable());\n    assertThat(value.nullableCount).isEqualTo(1);\n  }\n\n  @Test\n  public void nullableWithTypeAnnotation() {\n    assertThat(value.nullableWithTypeAnnotation())\n        .isEqualTo(\"nullable derived stringWithTypeAnnotation 1\");\n    assertThat(value.nullableWithTypeAnnotation())\n        .isSameInstanceAs(value.nullableWithTypeAnnotation());\n    assertThat(value.nullableWithTypeAnnotationCount).isEqualTo(1);\n  }\n\n  @Test\n  public void returnsNull() {\n    assertThat(value.returnsNull()).isNull();\n    assertThat(value.returnsNull()).isNull();\n    assertThat(value.returnsNullCount).isEqualTo(1);\n  }\n\n  @Test\n  public void returnsNullWithTypeAnnotation() {\n    assertThat(value.returnsNullWithTypeAnnotation()).isNull();\n    assertThat(value.returnsNullWithTypeAnnotation()).isNull();\n    assertThat(value.returnsNullWithTypeAnnotationCount).isEqualTo(1);\n  }\n\n  @Test\n  public void notNullableButReturnsNull() {\n    try {\n      value.notNullableButReturnsNull();\n      fail();\n    } catch (NullPointerException expected) {\n      assertThat(expected)\n          .hasMessageThat()\n          .isEqualTo(\"notNullableButReturnsNull() cannot return null\");\n    }\n    assertThat(value.notNullableButReturnsNullCount).isEqualTo(1);\n  }\n\n  @Test\n  public void methodThrows() {\n    // The exception is thrown.\n    try {\n      value.throwsException();\n      fail();\n    } catch (SomeCheckedException expected1) {\n      // The exception is not memoized.\n      try {\n        value.throwsException();\n        fail();\n      } catch (SomeCheckedException expected2) {\n        assertThat(expected2).isNotSameInstanceAs(expected1);\n      }\n    }\n    assertThat(value.throwsExceptionCount).isEqualTo(2);\n  }\n\n  @Test\n  public void testHashCode() {\n    assertThat(value.hashCode()).isEqualTo(value.hashCode());\n    assertThat(value.counter().hashCodeCount).isEqualTo(1);\n  }\n\n  @Test\n  public void testToString() {\n    assertThat(value.toString()).isEqualTo(value.toString());\n    assertThat(value.counter().toStringCount).isEqualTo(1);\n  }\n\n  @Test\n  public void keywords() throws Exception {\n    ValueWithKeywordName value =\n        new AutoValue_MemoizedTest_ValueWithKeywordName(true, false, \"foo\");\n    assertThat(value.getNative()).isTrue();\n    assertThat(value.getMemoizedNative()).isTrue();\n    assertThat(value.getNative0()).isFalse();\n    assertThat(value.getMemoizedNative0()).isFalse();\n\n    Constructor<?> constructor =\n        value.getClass().getDeclaredConstructor(boolean.class, boolean.class, String.class);\n    ImmutableList<String> names =\n        stream(constructor.getParameters()).map(Parameter::getName).collect(toImmutableList());\n    assertThat(names).contains(\"notKeyword\");\n  }\n\n  @Test\n  public void copyClassAnnotations_valueWithCopyAnnotations_copiesAnnotation() throws Exception {\n    ValueWithCopyAnnotations valueWithCopyAnnotations =\n        new AutoValue_MemoizedTest_ValueWithCopyAnnotations(\"test\");\n\n    assertThat(\n            valueWithCopyAnnotations\n                .getClass()\n                .isAnnotationPresent(javax.annotation.Nullable.class))\n        .isTrue();\n  }\n\n  @Test\n  public void copyClassAnnotations_valueWithoutCopyAnnotations_doesNotCopyAnnotation()\n      throws Exception {\n    ValueWithoutCopyAnnotations valueWithoutCopyAnnotations =\n        new AutoValue_MemoizedTest_ValueWithoutCopyAnnotations(\"test\");\n\n    assertThat(\n            valueWithoutCopyAnnotations\n                .getClass()\n                .isAnnotationPresent(javax.annotation.Nullable.class))\n        .isFalse();\n  }\n\n  @Test\n  public void copyClassAnnotations_valueWithExcludedCopyAnnotations_doesNotCopyAnnotation()\n      throws Exception {\n    ValueWithExcludedCopyAnnotations valueWithExcludedCopyAnnotations =\n        new AutoValue_MemoizedTest_ValueWithExcludedCopyAnnotations(\"test\");\n\n    assertThat(\n            valueWithExcludedCopyAnnotations\n                .getClass()\n                .isAnnotationPresent(javax.annotation.Nullable.class))\n        .isFalse();\n  }\n\n  @Test\n  public void copyMethodAnnotations_valueWithCopyAnnotations_copiesAnnotation() throws Exception {\n    ValueWithCopyAnnotations valueWithCopyAnnotations =\n        new AutoValue_MemoizedTest_ValueWithCopyAnnotations(\"test\");\n\n    assertThat(\n            valueWithCopyAnnotations\n                .getClass()\n                .getMethod(\"getMemoizedNative\")\n                .isAnnotationPresent(javax.annotation.Nullable.class))\n        .isTrue();\n  }\n\n  @Test\n  public void copyMethodAnnotations_valueWithoutCopyAnnotations_copiesAnnotation()\n      throws Exception {\n    ValueWithoutCopyAnnotations valueWithoutCopyAnnotations =\n        new AutoValue_MemoizedTest_ValueWithoutCopyAnnotations(\"test\");\n\n    assertThat(\n            valueWithoutCopyAnnotations\n                .getClass()\n                .getMethod(\"getMemoizedNative\")\n                .isAnnotationPresent(javax.annotation.Nullable.class))\n        .isTrue();\n  }\n\n  @Test\n  public void copyMethodAnnotations_valueWithExcludedCopyAnnotations_doesNotCopyAnnotation()\n      throws Exception {\n    ValueWithExcludedCopyAnnotations valueWithExcludedCopyAnnotations =\n        new AutoValue_MemoizedTest_ValueWithExcludedCopyAnnotations(\"test\");\n\n    assertThat(\n            valueWithExcludedCopyAnnotations\n                .getClass()\n                .getMethod(\"getMemoizedNative\")\n                .isAnnotationPresent(javax.annotation.Nullable.class))\n        .isFalse();\n  }\n\n  @Test\n  public void nullableHasAnnotation() throws ReflectiveOperationException {\n    Method nullable = AutoValue_MemoizedTest_Value.class.getDeclaredMethod(\"nullable\");\n    assertThat(nullable.isAnnotationPresent(javax.annotation.Nullable.class)).isTrue();\n  }\n\n  @Test\n  public void nullableWithTypeAnnotationHasAnnotation() throws ReflectiveOperationException {\n    Method nullable =\n        AutoValue_MemoizedTest_Value.class.getDeclaredMethod(\"nullableWithTypeAnnotation\");\n    AnnotatedType returnType = nullable.getAnnotatedReturnType();\n    assertThat(\n            returnType.isAnnotationPresent(\n                org.checkerframework.checker.nullness.qual.Nullable.class))\n        .isTrue();\n  }\n\n  @Test\n  public void nullableConstructorParameter() throws ReflectiveOperationException {\n    // Constructor parameters are potentially:\n    // [0] @javax.annotation.Nullable String string,\n    // [1] @org.checkerframework.checker.nullness.qual.Nullable String stringWithTypeAnnotation,\n    // [2] HashCodeAndToStringCounter counter\n    // We don't currently copy @javax.annotation.Nullable because it is not a TYPE_USE annotation.\n    Constructor<?> constructor =\n        AutoValue_MemoizedTest_Value.class.getDeclaredConstructor(\n            String.class, String.class, HashCodeAndToStringCounter.class);\n    AnnotatedType paramType = constructor.getAnnotatedParameterTypes()[1];\n    assertThat(\n            paramType.isAnnotationPresent(\n                org.checkerframework.checker.nullness.qual.Nullable.class))\n        .isTrue();\n  }\n\n  @Test\n  public void hashCodeEqualsOptimization() {\n    HashCodeEqualsOptimization first =\n        new AutoValue_MemoizedTest_HashCodeEqualsOptimization(new EqualsCounter());\n    HashCodeEqualsOptimization second =\n        new AutoValue_MemoizedTest_HashCodeEqualsOptimization(new EqualsCounter());\n\n    first.overrideHashCode = 2;\n    second.overrideHashCode = 2;\n    assertThat(first.equals(second)).isTrue();\n    assertThat(first.equalsCounter().equalsCount).isEqualTo(1);\n\n    HashCodeEqualsOptimization otherwiseEqualsButDifferentHashCode =\n        new AutoValue_MemoizedTest_HashCodeEqualsOptimization(new EqualsCounter());\n    otherwiseEqualsButDifferentHashCode.overrideHashCode = 4;\n\n    assertThat(otherwiseEqualsButDifferentHashCode.equals(first)).isFalse();\n    assertThat(otherwiseEqualsButDifferentHashCode.equalsCounter().equalsCount).isEqualTo(0);\n  }\n\n  @Test\n  public void hashCodeEqualsOptimization_otherTypes() {\n    HashCodeEqualsOptimization optimizedEquals =\n        new AutoValue_MemoizedTest_HashCodeEqualsOptimization(new EqualsCounter());\n\n    assertThat(optimizedEquals.equals(new Object())).isFalse();\n    assertThat(optimizedEquals.equals(null)).isFalse();\n\n    assertThat(optimizedEquals.equalsCounter().equalsCount).isEqualTo(0);\n    assertThat(optimizedEquals.hashCodeCount).isEqualTo(0);\n  }\n\n  @Test\n  public void hashCodeEqualsOptimization_hashCodeIgnoredForSameInstance() {\n    HashCodeEqualsOptimization optimizedEquals =\n        new AutoValue_MemoizedTest_HashCodeEqualsOptimization(new EqualsCounter());\n\n    assertThat(optimizedEquals.equals(optimizedEquals)).isTrue();\n\n    assertThat(optimizedEquals.equalsCounter().equalsCount).isEqualTo(0);\n    assertThat(optimizedEquals.hashCodeCount).isEqualTo(0);\n  }\n\n  @Test\n  public void hashCodeEqualsOptimization_offWhenEqualsIsFinal() {\n    HashCodeEqualsOptimizationOffWhenEqualsIsFinal memoizedHashCodeAndFinalEqualsMethod =\n        new AutoValue_MemoizedTest_HashCodeEqualsOptimizationOffWhenEqualsIsFinal();\n    HashCodeEqualsOptimizationOffWhenEqualsIsFinal second =\n        new AutoValue_MemoizedTest_HashCodeEqualsOptimizationOffWhenEqualsIsFinal();\n\n    assertThat(memoizedHashCodeAndFinalEqualsMethod.equals(second)).isTrue();\n    assertThat(memoizedHashCodeAndFinalEqualsMethod.hashCodeCount).isEqualTo(0);\n\n    int unused1 = memoizedHashCodeAndFinalEqualsMethod.hashCode();\n    int unused2 = memoizedHashCodeAndFinalEqualsMethod.hashCode();\n    assertThat(memoizedHashCodeAndFinalEqualsMethod.hashCodeCount).isEqualTo(1);\n  }\n\n  interface TypeEdgeIterable<InputT, ResultT> {}\n\n  interface ResourceUri {}\n\n  interface TypePath<InputT, ResultT> {}\n\n  abstract static class AbstractTypePath<InputT, ResultT> {\n    abstract TypeEdgeIterable<InputT, ResultT> edges();\n  }\n\n  @AutoValue\n  abstract static class ResourceUriPath<InputT> extends AbstractTypePath<InputT, ResourceUri> {\n    static <InputT> ResourceUriPath<InputT> create(TypeEdgeIterable<InputT, ResourceUri> edges) {\n      return new AutoValue_MemoizedTest_ResourceUriPath<>(edges);\n    }\n\n    @Memoized\n    TypePath<InputT, String> toServiceName() {\n      return new TypePath<InputT, String>() {};\n    }\n  }\n\n  @Test\n  public void methodTypeFromTypeVariableSubsitution() {\n    ResourceUriPath<String> path =\n        ResourceUriPath.create(new TypeEdgeIterable<String, ResourceUri>() {});\n    assertThat(path.edges()).isNotNull();\n  }\n\n  @Immutable\n  @AutoValue\n  abstract static class Unchanging<@ImmutableTypeParameter T> {\n    abstract T value();\n\n    @Override\n    @Memoized\n    public abstract int hashCode();\n\n    static <@ImmutableTypeParameter T> Unchanging<T> of(T value) {\n      return new AutoValue_MemoizedTest_Unchanging<T>(value);\n    }\n  }\n\n  @Test\n  public void copiedTypeAnnotations() {\n    for (Class<?> c = Unchanging.of(\"foo\").getClass(); c != Object.class; c = c.getSuperclass()) {\n      assertThat(c.getTypeParameters()).hasLength(1);\n      assertThat(c.getTypeParameters()[0].isAnnotationPresent(ImmutableTypeParameter.class))\n          .isTrue();\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/extension/memoized/MemoizedValidationTest.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.memoized;\n\nimport static com.google.auto.value.extension.memoized.MemoizedMethodSubjectFactory.assertThatMemoizeMethod;\nimport static com.google.testing.compile.CompilationSubject.assertThat;\nimport static com.google.testing.compile.Compiler.javac;\n\nimport com.google.auto.value.extension.memoized.processor.MemoizedValidator;\nimport com.google.testing.compile.Compilation;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic class MemoizedValidationTest {\n\n  @Test\n  public void privateMethod() {\n    assertThatMemoizeMethod(\"@Memoized private String method() { return \\\"\\\"; }\")\n        .hasError(\"@Memoized methods cannot be private\");\n  }\n\n  @Test\n  public void staticMethod() {\n    assertThatMemoizeMethod(\"@Memoized static String method() { return \\\"\\\"; }\")\n        .hasError(\"@Memoized methods cannot be static\");\n  }\n\n  @Test\n  public void finalMethod() {\n    assertThatMemoizeMethod(\"@Memoized final String method() { return \\\"\\\"; }\")\n        .hasError(\"@Memoized methods cannot be final\");\n  }\n\n  @Test\n  public void abstractMethod() {\n    assertThatMemoizeMethod(\"@Memoized abstract String method();\")\n        .hasError(\"@Memoized methods cannot be abstract\");\n  }\n\n  @Test\n  public void voidMethod() {\n    assertThatMemoizeMethod(\"@Memoized void method() {}\")\n        .hasError(\"@Memoized methods cannot be void\");\n  }\n\n  @Test\n  public void parameters() {\n    assertThatMemoizeMethod(\"@Memoized String method(Object param) { return \\\"\\\"; }\")\n        .hasError(\"@Memoized methods cannot have parameters\");\n  }\n\n  @Test\n  public void notInAutoValueClass() {\n    JavaFileObject source =\n        JavaFileObjects.forSourceLines(\n            \"test.EnclosingClass\",\n            \"package test;\",\n            \"\",\n            \"import com.google.auto.value.extension.memoized.Memoized;\",\n            \"\",\n            \"abstract class EnclosingClass {\",\n            \"  @Memoized\",\n            \"  String string() {\",\n            \"    return \\\"\\\";\",\n            \"  }\",\n            \"}\");\n    Compilation compilation = javac().withProcessors(new MemoizedValidator()).compile(source);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\"@Memoized methods must be declared only in @AutoValue classes\")\n        .inFile(source)\n        .onLine(6);\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/extension/serializable/processor/SerializableAutoValueExtensionTest.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.processor;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.assertThrows;\n\nimport com.google.auto.value.AutoValue;\nimport com.google.auto.value.extension.memoized.Memoized;\nimport com.google.auto.value.extension.serializable.SerializableAutoValue;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.testing.SerializableTester;\nimport java.io.ByteArrayOutputStream;\nimport java.io.NotSerializableException;\nimport java.io.ObjectOutputStream;\nimport java.io.Serializable;\nimport java.util.Optional;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic final class SerializableAutoValueExtensionTest {\n  private static final String A = \"a\";\n  private static final int B = 1;\n  private static final String C = \"c\";\n  private static final int D = 2;\n\n  @SerializableAutoValue\n  @AutoValue\n  abstract static class DummySerializableAutoValue implements Serializable {\n    // Primitive fields\n    abstract String a();\n\n    abstract int b();\n\n    // Optional fields\n    abstract Optional<String> optionalC();\n\n    abstract Optional<Integer> optionalD();\n\n    static DummySerializableAutoValue.Builder builder() {\n      return new AutoValue_SerializableAutoValueExtensionTest_DummySerializableAutoValue.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder {\n      abstract DummySerializableAutoValue.Builder setA(String value);\n\n      abstract DummySerializableAutoValue.Builder setB(int value);\n\n      abstract DummySerializableAutoValue.Builder setOptionalC(String value);\n\n      abstract DummySerializableAutoValue.Builder setOptionalD(int value);\n\n      abstract DummySerializableAutoValue build();\n    }\n  }\n\n  @Test\n  public void allFieldsAreSet_noEmpty() {\n    DummySerializableAutoValue autoValue =\n        DummySerializableAutoValue.builder()\n            .setA(A)\n            .setB(B)\n            .setOptionalC(C)\n            .setOptionalD(D)\n            .build();\n\n    assertThat(autoValue.a()).isEqualTo(A);\n    assertThat(autoValue.b()).isEqualTo(B);\n    assertThat(autoValue.optionalC()).hasValue(C);\n    assertThat(autoValue.optionalD()).hasValue(D);\n  }\n\n  @Test\n  public void allFieldsAreSet_withMixedEmpty() {\n    DummySerializableAutoValue autoValue =\n        DummySerializableAutoValue.builder().setA(A).setB(B).setOptionalC(C).build();\n\n    assertThat(autoValue.a()).isEqualTo(A);\n    assertThat(autoValue.b()).isEqualTo(B);\n    assertThat(autoValue.optionalC()).hasValue(C);\n    assertThat(autoValue.optionalD()).isEmpty();\n  }\n\n  @Test\n  public void allFieldsAreSet_withEmpty() {\n    DummySerializableAutoValue autoValue =\n        DummySerializableAutoValue.builder().setA(A).setB(B).build();\n\n    assertThat(autoValue.a()).isEqualTo(A);\n    assertThat(autoValue.b()).isEqualTo(B);\n    assertThat(autoValue.optionalC()).isEmpty();\n    assertThat(autoValue.optionalD()).isEmpty();\n  }\n\n  @Test\n  public void allFieldsAreSerialized_noEmpty() {\n    DummySerializableAutoValue autoValue =\n        DummySerializableAutoValue.builder()\n            .setA(A)\n            .setB(B)\n            .setOptionalC(C)\n            .setOptionalD(D)\n            .build();\n\n    DummySerializableAutoValue actualAutoValue = SerializableTester.reserialize(autoValue);\n\n    assertThat(actualAutoValue).isEqualTo(autoValue);\n  }\n\n  @Test\n  public void allFieldsAreSerialized_withEmpty() {\n    DummySerializableAutoValue autoValue =\n        DummySerializableAutoValue.builder().setA(A).setB(B).build();\n\n    DummySerializableAutoValue actualAutoValue = SerializableTester.reserialize(autoValue);\n\n    assertThat(actualAutoValue).isEqualTo(autoValue);\n  }\n\n  @Test\n  public void allFieldsAreSerialized_withMixedEmpty() {\n    DummySerializableAutoValue autoValue =\n        DummySerializableAutoValue.builder().setA(A).setB(B).setOptionalC(C).build();\n\n    DummySerializableAutoValue actualAutoValue = SerializableTester.reserialize(autoValue);\n\n    assertThat(actualAutoValue).isEqualTo(autoValue);\n  }\n\n  @SerializableAutoValue\n  @AutoValue\n  abstract static class PrefixSerializableAutoValue implements Serializable {\n    // Primitive fields\n    abstract String getA();\n\n    abstract boolean isB();\n\n    // Optional fields\n    abstract Optional<String> getC();\n\n    abstract Optional<Boolean> getD();\n\n    static PrefixSerializableAutoValue.Builder builder() {\n      return new AutoValue_SerializableAutoValueExtensionTest_PrefixSerializableAutoValue.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder {\n      abstract PrefixSerializableAutoValue.Builder a(String value);\n\n      abstract PrefixSerializableAutoValue.Builder b(boolean value);\n\n      abstract PrefixSerializableAutoValue.Builder c(String value);\n\n      abstract PrefixSerializableAutoValue.Builder d(boolean value);\n\n      abstract PrefixSerializableAutoValue build();\n    }\n  }\n\n  @Test\n  public void allPrefixFieldsAreSerialized_noEmpty() {\n    PrefixSerializableAutoValue autoValue =\n        PrefixSerializableAutoValue.builder().a(\"A\").b(true).c(\"C\").d(false).build();\n\n    PrefixSerializableAutoValue actualAutoValue = SerializableTester.reserialize(autoValue);\n\n    assertThat(actualAutoValue).isEqualTo(autoValue);\n  }\n\n  @Test\n  public void allPrefixFieldsAreSerialized_WithEmpty() {\n    PrefixSerializableAutoValue autoValue =\n        PrefixSerializableAutoValue.builder().a(\"A\").b(true).build();\n\n    PrefixSerializableAutoValue actualAutoValue = SerializableTester.reserialize(autoValue);\n\n    assertThat(actualAutoValue).isEqualTo(autoValue);\n  }\n\n  @SerializableAutoValue\n  @AutoValue\n  abstract static class NotSerializable {\n    static NotSerializable create() {\n      return new AutoValue_SerializableAutoValueExtensionTest_NotSerializable(Optional.of(\"A\"));\n    }\n\n    abstract Optional<String> optionalA();\n  }\n\n  @Test\n  public void missingImplementsSerializableThrowsException() throws Exception {\n    NotSerializable autoValue = NotSerializable.create();\n    ByteArrayOutputStream bo = new ByteArrayOutputStream();\n    ObjectOutputStream so = new ObjectOutputStream(bo);\n\n    assertThrows(NotSerializableException.class, () -> so.writeObject(autoValue));\n  }\n\n  @AutoValue\n  abstract static class NotSerializableNoAnnotation implements Serializable {\n    static NotSerializableNoAnnotation create() {\n      return new AutoValue_SerializableAutoValueExtensionTest_NotSerializableNoAnnotation(\n          Optional.of(\"A\"));\n    }\n\n    abstract Optional<String> optionalA();\n  }\n\n  @Test\n  public void missingSerializableAutoValueAnnotationThrowsException() throws Exception {\n    NotSerializableNoAnnotation autoValue = NotSerializableNoAnnotation.create();\n    ByteArrayOutputStream bo = new ByteArrayOutputStream();\n    ObjectOutputStream so = new ObjectOutputStream(bo);\n\n    assertThrows(NotSerializableException.class, () -> so.writeObject(autoValue));\n  }\n\n  @SerializableAutoValue\n  @AutoValue\n  // Technically all type parameters should extend serializable, but for the purposes of testing,\n  // only one type parameter is bounded.\n  abstract static class HasTypeParameters<T extends Serializable, S> implements Serializable {\n    abstract T a();\n\n    abstract Optional<S> optionalB();\n\n    static <T extends Serializable, S> Builder<T, S> builder() {\n      return new AutoValue_SerializableAutoValueExtensionTest_HasTypeParameters.Builder<>();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder<T extends Serializable, S> {\n      abstract Builder<T, S> setA(T value);\n\n      abstract Builder<T, S> setOptionalB(S value);\n\n      abstract HasTypeParameters<T, S> build();\n    }\n  }\n\n  @Test\n  public void typeParameterizedFieldsAreSet_noEmpty() {\n    HasTypeParameters<String, Integer> autoValue =\n        HasTypeParameters.<String, Integer>builder().setA(A).setOptionalB(B).build();\n\n    assertThat(autoValue.a()).isEqualTo(A);\n    assertThat(autoValue.optionalB()).hasValue(B);\n  }\n\n  @Test\n  public void typeParameterizedFieldsAreSet_withEmpty() {\n    HasTypeParameters<String, Integer> autoValue =\n        HasTypeParameters.<String, Integer>builder().setA(A).build();\n\n    assertThat(autoValue.a()).isEqualTo(A);\n    assertThat(autoValue.optionalB()).isEmpty();\n  }\n\n  @Test\n  public void typeParameterizedFieldsAreSerializable_noEmpty() {\n    HasTypeParameters<String, Integer> autoValue =\n        HasTypeParameters.<String, Integer>builder().setA(A).setOptionalB(B).build();\n\n    HasTypeParameters<String, Integer> actualAutoValue = SerializableTester.reserialize(autoValue);\n\n    assertThat(actualAutoValue).isEqualTo(autoValue);\n  }\n\n  @Test\n  public void typeParameterizedFieldsAreSerializable_withEmpty() {\n    HasTypeParameters<String, Integer> autoValue =\n        HasTypeParameters.<String, Integer>builder().setA(A).build();\n\n    HasTypeParameters<String, Integer> actualAutoValue = SerializableTester.reserialize(autoValue);\n\n    assertThat(actualAutoValue).isEqualTo(autoValue);\n  }\n\n  @SerializableAutoValue\n  @AutoValue\n  abstract static class ImmutableListSerializableAutoValue implements Serializable {\n    abstract ImmutableList<Optional<String>> payload();\n\n    static ImmutableListSerializableAutoValue.Builder builder() {\n      return new AutoValue_SerializableAutoValueExtensionTest_ImmutableListSerializableAutoValue\n          .Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder {\n      abstract ImmutableListSerializableAutoValue.Builder setPayload(\n          ImmutableList<Optional<String>> payload);\n\n      abstract ImmutableListSerializableAutoValue build();\n    }\n  }\n\n  @Test\n  public void immutableList_emptyListSerialized() {\n    ImmutableListSerializableAutoValue autoValue =\n        ImmutableListSerializableAutoValue.builder().setPayload(ImmutableList.of()).build();\n\n    ImmutableListSerializableAutoValue actualAutoValue = SerializableTester.reserialize(autoValue);\n\n    assertThat(actualAutoValue).isEqualTo(autoValue);\n  }\n\n  @Test\n  public void immutableList_allFieldsSetAndSerialized() {\n    ImmutableListSerializableAutoValue autoValue =\n        ImmutableListSerializableAutoValue.builder()\n            .setPayload(ImmutableList.of(Optional.of(\"a1\"), Optional.of(\"a2\")))\n            .build();\n\n    ImmutableListSerializableAutoValue actualAutoValue = SerializableTester.reserialize(autoValue);\n\n    assertThat(actualAutoValue).isEqualTo(autoValue);\n  }\n\n  @SerializableAutoValue\n  @AutoValue\n  abstract static class ImmutableMapSerializableAutoValue implements Serializable {\n    abstract ImmutableMap<Optional<String>, String> a();\n\n    abstract ImmutableMap<String, Optional<String>> b();\n\n    static ImmutableMapSerializableAutoValue.Builder builder() {\n      return new AutoValue_SerializableAutoValueExtensionTest_ImmutableMapSerializableAutoValue\n          .Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder {\n      abstract ImmutableMapSerializableAutoValue.Builder setA(\n          ImmutableMap<Optional<String>, String> a);\n\n      abstract ImmutableMapSerializableAutoValue.Builder setB(\n          ImmutableMap<String, Optional<String>> b);\n\n      abstract ImmutableMapSerializableAutoValue build();\n    }\n  }\n\n  @Test\n  public void immutableMap_emptyMapSerialized() {\n    ImmutableMapSerializableAutoValue autoValue =\n        ImmutableMapSerializableAutoValue.builder()\n            .setA(ImmutableMap.of())\n            .setB(ImmutableMap.of())\n            .build();\n\n    ImmutableMapSerializableAutoValue actualAutoValue = SerializableTester.reserialize(autoValue);\n\n    assertThat(actualAutoValue).isEqualTo(autoValue);\n  }\n\n  @Test\n  public void immutableMap_allFieldsSetAndSerialized() {\n    ImmutableMapSerializableAutoValue autoValue =\n        ImmutableMapSerializableAutoValue.builder()\n            .setA(ImmutableMap.of(Optional.of(\"key\"), \"value\"))\n            .setB(ImmutableMap.of(\"key\", Optional.of(\"value\")))\n            .build();\n\n    ImmutableMapSerializableAutoValue actualAutoValue = SerializableTester.reserialize(autoValue);\n\n    assertThat(actualAutoValue).isEqualTo(autoValue);\n  }\n\n  @SerializableAutoValue\n  @AutoValue\n  abstract static class MultiplePropertiesSameType implements Serializable {\n    abstract String a();\n\n    abstract String b();\n\n    static MultiplePropertiesSameType.Builder builder() {\n      return new AutoValue_SerializableAutoValueExtensionTest_MultiplePropertiesSameType.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder {\n      abstract MultiplePropertiesSameType.Builder setA(String value);\n\n      abstract MultiplePropertiesSameType.Builder setB(String value);\n\n      abstract MultiplePropertiesSameType build();\n    }\n  }\n\n  @Test\n  public void multiplePropertiesSameType_allFieldsSerialized() {\n    MultiplePropertiesSameType autoValue =\n        MultiplePropertiesSameType.builder().setA(\"A\").setB(\"B\").build();\n\n    MultiplePropertiesSameType actualAutoValue = SerializableTester.reserialize(autoValue);\n\n    assertThat(actualAutoValue).isEqualTo(autoValue);\n  }\n\n  /**\n   * Type that may result in nested lambdas in the generated code. Including this allows us to\n   * verify that we handle those correctly, in particular not reusing a lambda parameter name in\n   * another lambda nested inside the first one.\n   */\n  @SerializableAutoValue\n  @AutoValue\n  abstract static class ComplexType implements Serializable {\n    abstract ImmutableMap<String, ImmutableMap<String, Optional<String>>> a();\n\n    static ComplexType.Builder builder() {\n      return new AutoValue_SerializableAutoValueExtensionTest_ComplexType.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder {\n      abstract ComplexType.Builder setA(\n          ImmutableMap<String, ImmutableMap<String, Optional<String>>> a);\n\n      abstract ComplexType build();\n    }\n  }\n\n  @Test\n  public void complexType() {\n    ImmutableMap<String, ImmutableMap<String, Optional<String>>> map =\n        ImmutableMap.of(\"foo\", ImmutableMap.of(\"bar\", Optional.of(\"baz\")));\n    ComplexType complexType = ComplexType.builder().setA(map).build();\n\n    ComplexType reserialized = SerializableTester.reserialize(complexType);\n\n    assertThat(reserialized).isEqualTo(complexType);\n  }\n\n  /**\n   * Type that uses both {@code @SerializableAutoValue} and {@code @Memoized}, showing that the two\n   * extensions work correctly together.\n   */\n  @SerializableAutoValue\n  @AutoValue\n  abstract static class SerializeMemoize implements Serializable {\n    abstract Optional<Integer> number();\n\n    private transient int methodCount;\n\n    @Memoized\n    Optional<Integer> negate() {\n      methodCount++;\n      return number().map(n -> -n);\n    }\n\n    static SerializeMemoize.Builder builder() {\n      return new AutoValue_SerializableAutoValueExtensionTest_SerializeMemoize.Builder();\n    }\n\n    @AutoValue.Builder\n    abstract static class Builder {\n      abstract Builder setNumber(Optional<Integer> number);\n\n      abstract SerializeMemoize build();\n    }\n  }\n\n  @Test\n  public void serializeMemoize() {\n    SerializeMemoize instance1 = SerializeMemoize.builder().setNumber(Optional.of(17)).build();\n    assertThat(instance1.methodCount).isEqualTo(0);\n    assertThat(instance1.negate()).hasValue(-17);\n    assertThat(instance1.methodCount).isEqualTo(1);\n    assertThat(instance1.negate()).hasValue(-17);\n    assertThat(instance1.methodCount).isEqualTo(1);\n    SerializeMemoize instance2 = SerializableTester.reserialize(instance1);\n    assertThat(instance2.methodCount).isEqualTo(0);\n    assertThat(instance2.negate()).hasValue(-17);\n    assertThat(instance2.methodCount).isEqualTo(1);\n    assertThat(instance2.negate()).hasValue(-17);\n    assertThat(instance2.methodCount).isEqualTo(1);\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/extension/serializable/serializer/SerializerFactoryLoaderTest.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.serializer;\n\nimport static com.google.common.truth.Truth.assertThat;\n\nimport com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.SerializerFactory;\nimport com.google.auto.value.extension.serializable.serializer.utils.CompilationAbstractTest;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic final class SerializerFactoryLoaderTest extends CompilationAbstractTest {\n\n  @Test\n  public void getFactory_extensionsLoaded() throws Exception {\n    SerializerFactory factory = SerializerFactoryLoader.getFactory(mockProcessingEnvironment);\n\n    Serializer actualSerializer = factory.getSerializer(typeMirrorOf(String.class));\n\n    assertThat(actualSerializer.getClass().getName())\n        .contains(\"TestStringSerializerFactory$TestStringSerializer\");\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/IdentitySerializerFactoryTest.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.serializer.impl;\n\nimport static com.google.common.truth.Truth.assertThat;\n\nimport com.google.auto.value.extension.serializable.serializer.utils.CompilationAbstractTest;\nimport com.squareup.javapoet.CodeBlock;\nimport javax.lang.model.type.TypeMirror;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic final class IdentitySerializerFactoryTest extends CompilationAbstractTest {\n\n  @Test\n  public void proxyFieldType_isUnchanged() throws Exception {\n    TypeMirror typeMirror = typeMirrorOf(String.class);\n\n    TypeMirror actualTypeMirror =\n        IdentitySerializerFactory.getSerializer(typeMirror).proxyFieldType();\n\n    assertThat(actualTypeMirror).isSameInstanceAs(typeMirror);\n  }\n\n  @Test\n  public void toProxy_isUnchanged() throws Exception {\n    TypeMirror typeMirror = typeMirrorOf(String.class);\n    CodeBlock inputExpression = CodeBlock.of(\"x\");\n\n    CodeBlock outputExpression =\n        IdentitySerializerFactory.getSerializer(typeMirror).toProxy(inputExpression);\n\n    assertThat(outputExpression).isSameInstanceAs(inputExpression);\n  }\n\n  @Test\n  public void fromProxy_isUnchanged() throws Exception {\n    TypeMirror typeMirror = typeMirrorOf(String.class);\n    CodeBlock inputExpression = CodeBlock.of(\"x\");\n\n    CodeBlock outputExpression =\n        IdentitySerializerFactory.getSerializer(typeMirror).fromProxy(inputExpression);\n\n    assertThat(outputExpression).isSameInstanceAs(inputExpression);\n  }\n\n  @Test\n  public void isIdentity() throws Exception {\n    TypeMirror typeMirror = typeMirrorOf(String.class);\n\n    boolean actualIsIdentity = IdentitySerializerFactory.getSerializer(typeMirror).isIdentity();\n\n    assertThat(actualIsIdentity).isTrue();\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/ImmutableListSerializerExtensionTest.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.serializer.impl;\n\nimport static com.google.common.truth.Truth.assertThat;\n\nimport com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;\nimport com.google.auto.value.extension.serializable.serializer.utils.CompilationAbstractTest;\nimport com.google.auto.value.extension.serializable.serializer.utils.FakeSerializerFactory;\nimport com.google.common.collect.ImmutableList;\nimport com.squareup.javapoet.CodeBlock;\nimport java.util.Optional;\nimport javax.lang.model.type.TypeMirror;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic final class ImmutableListSerializerExtensionTest extends CompilationAbstractTest {\n\n  private static final String FUNCTION_WITH_EXCEPTIONS =\n      \"com.google.auto.value.extension.serializable.serializer.runtime.FunctionWithExceptions\";\n  private static final String IMMUTABLE_LIST = \"com.google.common.collect.ImmutableList\";\n\n  private ImmutableListSerializerExtension extension;\n  private FakeSerializerFactory fakeSerializerFactory;\n\n  @Before\n  public void setUpExtension() {\n    extension = new ImmutableListSerializerExtension();\n    fakeSerializerFactory = new FakeSerializerFactory();\n    fakeSerializerFactory.setReturnIdentitySerializer(false);\n  }\n\n  @Test\n  public void getSerializer_nonImmutableList_emptyReturned() {\n    TypeMirror typeMirror = typeMirrorOf(String.class);\n\n    Optional<Serializer> actualSerializer =\n        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment);\n\n    assertThat(actualSerializer).isEmpty();\n  }\n\n  @Test\n  public void getSerializer_immutableListWithSerializableContainedType_emptyReturned() {\n    fakeSerializerFactory.setReturnIdentitySerializer(true);\n    TypeMirror typeMirror = typeMirrorOf(ImmutableList.class);\n\n    Optional<Serializer> actualSerializer =\n        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment);\n\n    assertThat(actualSerializer).isEmpty();\n  }\n\n  @Test\n  public void getSerializer_immutableList_serializerReturned() {\n    TypeMirror typeMirror = typeMirrorOf(ImmutableList.class);\n\n    Serializer actualSerializer =\n        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();\n\n    assertThat(actualSerializer.getClass().getName())\n        .contains(\"ImmutableListSerializerExtension$ImmutableListSerializer\");\n  }\n\n  @Test\n  public void proxyFieldType() {\n    TypeMirror typeMirror = declaredTypeOf(ImmutableList.class, Integer.class);\n\n    Serializer serializer =\n        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();\n    TypeMirror actualTypeMirror = serializer.proxyFieldType();\n\n    assertThat(typeUtils.isSameType(actualTypeMirror, typeMirror)).isTrue();\n  }\n\n  @Test\n  public void toProxy() {\n    TypeMirror typeMirror = declaredTypeOf(ImmutableList.class, Integer.class);\n\n    Serializer serializer =\n        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();\n    CodeBlock actualCodeBlock = serializer.toProxy(CodeBlock.of(\"x\"));\n\n    assertThat(actualCodeBlock.toString())\n        .isEqualTo(\n            String.format(\n                \"x.stream().map(%s.wrapper(value$ -> value$)).collect(%s.toImmutableList())\",\n                FUNCTION_WITH_EXCEPTIONS, IMMUTABLE_LIST));\n  }\n\n  @Test\n  public void fromProxy() {\n    TypeMirror typeMirror = declaredTypeOf(ImmutableList.class, Integer.class);\n\n    Serializer serializer =\n        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();\n    CodeBlock actualCodeBlock = serializer.fromProxy(CodeBlock.of(\"x\"));\n\n    assertThat(actualCodeBlock.toString())\n        .isEqualTo(\n            String.format(\n                \"x.stream().map(%s.wrapper(value$ -> value$)).collect(%s.toImmutableList())\",\n                FUNCTION_WITH_EXCEPTIONS, IMMUTABLE_LIST));\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/ImmutableMapSerializerExtensionTest.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.serializer.impl;\n\nimport static com.google.common.truth.Truth.assertThat;\n\nimport com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;\nimport com.google.auto.value.extension.serializable.serializer.utils.CompilationAbstractTest;\nimport com.google.auto.value.extension.serializable.serializer.utils.FakeSerializerFactory;\nimport com.google.common.collect.ImmutableMap;\nimport com.squareup.javapoet.CodeBlock;\nimport java.util.Optional;\nimport javax.lang.model.type.TypeMirror;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic final class ImmutableMapSerializerExtensionTest extends CompilationAbstractTest {\n\n  private static final String FUNCTION_WITH_EXCEPTIONS =\n      \"com.google.auto.value.extension.serializable.serializer.runtime.FunctionWithExceptions\";\n  private static final String IMMUTABLE_MAP = \"com.google.common.collect.ImmutableMap\";\n  private static final String INTEGER = \"java.lang.Integer\";\n  private static final String STRING = \"java.lang.String\";\n\n  private ImmutableMapSerializerExtension extension;\n  private FakeSerializerFactory fakeSerializerFactory;\n\n  @Before\n  public void setUpExtension() {\n    extension = new ImmutableMapSerializerExtension();\n    fakeSerializerFactory = new FakeSerializerFactory();\n    fakeSerializerFactory.setReturnIdentitySerializer(false);\n  }\n\n  @Test\n  public void getSerializer_nonImmutableMap_emptyReturned() {\n    TypeMirror typeMirror = typeMirrorOf(String.class);\n\n    Optional<Serializer> actualSerializer =\n        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment);\n\n    assertThat(actualSerializer).isEmpty();\n  }\n\n  @Test\n  public void getSerializer_immutableMapWithSerializableContainedTypes_emptyReturned() {\n    fakeSerializerFactory.setReturnIdentitySerializer(true);\n    TypeMirror typeMirror = typeMirrorOf(ImmutableMap.class);\n\n    Optional<Serializer> actualSerializer =\n        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment);\n\n    assertThat(actualSerializer).isEmpty();\n  }\n\n  @Test\n  public void getSerializer_immutableMap_serializerReturned() {\n    TypeMirror typeMirror = typeMirrorOf(ImmutableMap.class);\n\n    Serializer actualSerializer =\n        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();\n\n    assertThat(actualSerializer.getClass().getName())\n        .contains(\"ImmutableMapSerializerExtension$ImmutableMapSerializer\");\n  }\n\n  @Test\n  public void proxyFieldType() {\n    TypeMirror typeMirror = declaredTypeOf(ImmutableMap.class, Integer.class, String.class);\n\n    Serializer serializer =\n        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();\n    TypeMirror actualTypeMirror = serializer.proxyFieldType();\n\n    assertThat(typeUtils.isSameType(actualTypeMirror, typeMirror)).isTrue();\n  }\n\n  @Test\n  public void toProxy() {\n    TypeMirror typeMirror = declaredTypeOf(ImmutableMap.class, Integer.class, String.class);\n\n    Serializer serializer =\n        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();\n    CodeBlock actualCodeBlock = serializer.toProxy(CodeBlock.of(\"x\"));\n\n    assertThat(actualCodeBlock.toString())\n        .isEqualTo(\n            String.format(\n                \"x.entrySet().stream().collect(%s.toImmutableMap(value$ -> %s.<%s,\"\n                    + \" %s>wrapper(element$ -> element$).apply(value$.getKey()), value$ -> %s.<%s,\"\n                    + \" %s>wrapper(element$ -> element$).apply(value$.getValue())))\",\n                IMMUTABLE_MAP,\n                FUNCTION_WITH_EXCEPTIONS,\n                INTEGER,\n                INTEGER,\n                FUNCTION_WITH_EXCEPTIONS,\n                STRING,\n                STRING));\n  }\n\n  @Test\n  public void fromProxy() {\n    TypeMirror typeMirror = declaredTypeOf(ImmutableMap.class, Integer.class, String.class);\n\n    Serializer serializer =\n        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();\n    CodeBlock actualCodeBlock = serializer.fromProxy(CodeBlock.of(\"x\"));\n\n    assertThat(actualCodeBlock.toString())\n        .isEqualTo(\n            String.format(\n                \"x.entrySet().stream().collect(%s.toImmutableMap(value$ -> %s.<%s,\"\n                    + \" %s>wrapper(element$ -> element$).apply(value$.getKey()), value$ -> %s.<%s,\"\n                    + \" %s>wrapper(element$ -> element$).apply(value$.getValue())))\",\n                IMMUTABLE_MAP,\n                FUNCTION_WITH_EXCEPTIONS,\n                INTEGER,\n                INTEGER,\n                FUNCTION_WITH_EXCEPTIONS,\n                STRING,\n                STRING));\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/OptionalSerializerExtensionTest.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.serializer.impl;\n\nimport static com.google.common.truth.Truth.assertThat;\n\nimport com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;\nimport com.google.auto.value.extension.serializable.serializer.utils.CompilationAbstractTest;\nimport com.google.auto.value.extension.serializable.serializer.utils.FakeSerializerFactory;\nimport com.squareup.javapoet.CodeBlock;\nimport java.util.Optional;\nimport javax.lang.model.type.TypeMirror;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic final class OptionalSerializerExtensionTest extends CompilationAbstractTest {\n\n  private OptionalSerializerExtension extension;\n  private FakeSerializerFactory fakeSerializerFactory;\n\n  @Before\n  public void setUpExtension() {\n    extension = new OptionalSerializerExtension();\n    fakeSerializerFactory = new FakeSerializerFactory();\n  }\n\n  @Test\n  public void getSerializer_nonOptional_emptyReturned() {\n    TypeMirror typeMirror = typeMirrorOf(String.class);\n\n    Optional<Serializer> actualSerializer =\n        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment);\n\n    assertThat(actualSerializer).isEmpty();\n  }\n\n  @Test\n  public void getSerializer_optional_serializerReturned() {\n    TypeMirror typeMirror = typeMirrorOf(Optional.class);\n\n    Serializer actualSerializer =\n        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();\n\n    assertThat(actualSerializer.getClass().getName())\n        .contains(\"OptionalSerializerExtension$OptionalSerializer\");\n  }\n\n  @Test\n  public void proxyFieldType() {\n    TypeMirror typeMirror = declaredTypeOf(Optional.class, Integer.class);\n\n    Serializer serializer =\n        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();\n    TypeMirror actualTypeMirror = serializer.proxyFieldType();\n\n    assertThat(actualTypeMirror).isEqualTo(typeMirrorOf(Integer.class));\n  }\n\n  @Test\n  public void toProxy() {\n    TypeMirror typeMirror = declaredTypeOf(Optional.class, Integer.class);\n\n    Serializer serializer =\n        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();\n    CodeBlock actualCodeBlock = serializer.toProxy(CodeBlock.of(\"x\"));\n\n    assertThat(actualCodeBlock.toString()).isEqualTo(\"x.isPresent() ? x.get() : null\");\n  }\n\n  @Test\n  public void fromProxy() {\n    TypeMirror typeMirror = declaredTypeOf(Optional.class, Integer.class);\n\n    Serializer serializer =\n        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();\n    CodeBlock actualCodeBlock = serializer.fromProxy(CodeBlock.of(\"x\"));\n\n    assertThat(actualCodeBlock.toString())\n        .isEqualTo(\"java.util.Optional.ofNullable(x == null ? null : x)\");\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/SerializerFactoryImplTest.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.serializer.impl;\n\nimport static com.google.common.truth.Truth.assertThat;\n\nimport com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;\nimport com.google.auto.value.extension.serializable.serializer.utils.CompilationAbstractTest;\nimport com.google.auto.value.extension.serializable.serializer.utils.TestStringSerializerFactory;\nimport com.google.common.collect.ImmutableList;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic final class SerializerFactoryImplTest extends CompilationAbstractTest {\n\n  @Test\n  public void getSerializer_emptyFactories_identitySerializerReturned() throws Exception {\n    SerializerFactoryImpl factory =\n        new SerializerFactoryImpl(ImmutableList.of(), mockProcessingEnvironment);\n\n    Serializer actualSerializer = factory.getSerializer(typeMirrorOf(String.class));\n\n    assertThat(actualSerializer.getClass().getName())\n        .contains(\"IdentitySerializerFactory$IdentitySerializer\");\n  }\n\n  @Test\n  public void getSerializer_factoriesProvided_factoryReturned() throws Exception {\n    SerializerFactoryImpl factory =\n        new SerializerFactoryImpl(\n            ImmutableList.of(new TestStringSerializerFactory()), mockProcessingEnvironment);\n\n    Serializer actualSerializer = factory.getSerializer(typeMirrorOf(String.class));\n\n    assertThat(actualSerializer.getClass().getName())\n        .contains(\"TestStringSerializerFactory$TestStringSerializer\");\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/extension/serializable/serializer/utils/CompilationAbstractTest.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.serializer.utils;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.Iterables;\nimport com.google.common.reflect.Reflection;\nimport com.google.testing.compile.CompilationRule;\nimport java.lang.reflect.InvocationHandler;\nimport java.util.Arrays;\nimport javax.annotation.processing.Messager;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.Types;\nimport org.junit.Before;\nimport org.junit.Rule;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic abstract class CompilationAbstractTest {\n\n  @Rule public final CompilationRule compilationRule = new CompilationRule();\n\n  protected ProcessingEnvironment mockProcessingEnvironment = mockProcessingEnvironment();\n  protected Messager mockMessager = mockMessager();\n\n  protected Types typeUtils;\n  protected Elements elementUtils;\n\n  private ProcessingEnvironment mockProcessingEnvironment() {\n    InvocationHandler handler =\n        (proxy, method, args) -> {\n          switch (method.getName()) {\n            case \"getTypeUtils\":\n              return typeUtils;\n            case \"getElementUtils\":\n              return elementUtils;\n            case \"getMessager\":\n              return mockMessager;\n            case \"getOptions\":\n              return ImmutableMap.of();\n            case \"toString\":\n              return \"MockProcessingEnvironment\";\n            default:\n              throw new IllegalArgumentException(\"Unsupported method: \" + method);\n          }\n        };\n    return Reflection.newProxy(ProcessingEnvironment.class, handler);\n  }\n\n  private Messager mockMessager() {\n    InvocationHandler handler = (proxy, method, args) -> null;\n    return Reflection.newProxy(Messager.class, handler);\n  }\n\n  @Before\n  public final void setUp() {\n    typeUtils = compilationRule.getTypes();\n    elementUtils = compilationRule.getElements();\n  }\n\n  protected TypeElement typeElementOf(Class<?> c) {\n    return elementUtils.getTypeElement(c.getCanonicalName());\n  }\n\n  protected TypeMirror typeMirrorOf(Class<?> c) {\n    return typeElementOf(c).asType();\n  }\n\n  protected DeclaredType declaredTypeOf(Class<?> enclosingClass, Class<?> containedClass) {\n    return typeUtils.getDeclaredType(typeElementOf(enclosingClass), typeMirrorOf(containedClass));\n  }\n\n  protected DeclaredType declaredTypeOf(Class<?> enclosingClass, Class<?>... classArgs) {\n    return typeUtils.getDeclaredType(\n        typeElementOf(enclosingClass),\n        Iterables.toArray(\n            Arrays.stream(classArgs)\n                .map(this::typeMirrorOf)\n                .collect(ImmutableList.toImmutableList()),\n            TypeMirror.class));\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/extension/serializable/serializer/utils/FakeSerializerFactory.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.serializer.utils;\n\nimport com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.SerializerFactory;\nimport com.squareup.javapoet.CodeBlock;\nimport javax.lang.model.type.TypeMirror;\n\n/** A fake {@link SerializerFactory} that returns an identity serializer used for tests. */\npublic final class FakeSerializerFactory implements SerializerFactory {\n\n  private boolean isIdentity = true;\n\n  public FakeSerializerFactory() {}\n\n  /**\n   * Set if this factory should return a serializer that is considered an identity serializer.\n   *\n   * <p>The underlying fake serializer implementation will always be an identity serializer. This\n   * only changes the {@link Serializer#isIdentity} return value.\n   */\n  public void setReturnIdentitySerializer(boolean isIdentity) {\n    this.isIdentity = isIdentity;\n  }\n\n  @Override\n  public Serializer getSerializer(TypeMirror type) {\n    return new FakeIdentitySerializer(type, isIdentity);\n  }\n\n  // This doesn't follow the contract, and always returns the same string for a given prefix.\n  // That means it will be wrong if two identifiers with the same prefix are in the same scope in\n  // the generated code, but for our purposes in this fake it is OK, and means we don't have to\n  // hardwire knowledge of the uniqueness algorithm into golden text in tests.\n  @Override\n  public CodeBlock newIdentifier(String prefix) {\n    return CodeBlock.of(\"$L$$\", prefix);\n  }\n\n  private static class FakeIdentitySerializer implements Serializer {\n\n    private final TypeMirror typeMirror;\n    private final boolean isIdentity;\n\n    FakeIdentitySerializer(TypeMirror typeMirror, boolean isIdentity) {\n      this.typeMirror = typeMirror;\n      this.isIdentity = isIdentity;\n    }\n\n    @Override\n    public TypeMirror proxyFieldType() {\n      return typeMirror;\n    }\n\n    @Override\n    public CodeBlock toProxy(CodeBlock expression) {\n      return expression;\n    }\n\n    @Override\n    public CodeBlock fromProxy(CodeBlock expression) {\n      return expression;\n    }\n\n    @Override\n    public boolean isIdentity() {\n      return isIdentity;\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/extension/serializable/serializer/utils/TestStringSerializerFactory.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.extension.serializable.serializer.utils;\n\nimport com.google.auto.common.MoreElements;\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.service.AutoService;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.SerializerExtension;\nimport com.google.auto.value.extension.serializable.serializer.interfaces.SerializerFactory;\nimport com.squareup.javapoet.CodeBlock;\nimport java.util.Optional;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\n\n/** A test implementation of {@link SerializerExtension} that overwrites a string field's value. */\n@AutoService(SerializerExtension.class)\npublic final class TestStringSerializerFactory implements SerializerExtension {\n\n  public TestStringSerializerFactory() {}\n\n  @Override\n  public Optional<Serializer> getSerializer(\n      TypeMirror typeMirror, SerializerFactory factory, ProcessingEnvironment processingEnv) {\n    if (typeMirror.getKind() != TypeKind.DECLARED) {\n      return Optional.empty();\n    }\n\n    DeclaredType declaredType = MoreTypes.asDeclared(typeMirror);\n    TypeElement typeElement = MoreElements.asType(declaredType.asElement());\n    if (typeElement.getQualifiedName().contentEquals(\"java.lang.String\")) {\n      return Optional.of(new TestStringSerializer(typeMirror));\n    }\n\n    return Optional.empty();\n  }\n\n  private static class TestStringSerializer implements Serializer {\n\n    private final TypeMirror typeMirror;\n\n    TestStringSerializer(TypeMirror typeMirror) {\n      this.typeMirror = typeMirror;\n    }\n\n    @Override\n    public TypeMirror proxyFieldType() {\n      return typeMirror;\n    }\n\n    @Override\n    public CodeBlock toProxy(CodeBlock expression) {\n      return CodeBlock.of(\"$S\", \"test\");\n    }\n\n    @Override\n    public CodeBlock fromProxy(CodeBlock expression) {\n      return CodeBlock.of(\"$S\", \"test\");\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/extension/toprettystring/ToPrettyStringTest.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.auto.value.extension.toprettystring;\n\nimport static com.google.common.truth.Truth.assertThat;\n\nimport com.google.auto.value.AutoValue;\nimport com.google.auto.value.extension.toprettystring.ToPrettyStringTest.CollectionSubtypesWithFixedTypeParameters.StringList;\nimport com.google.auto.value.extension.toprettystring.ToPrettyStringTest.CollectionSubtypesWithFixedTypeParameters.StringMap;\nimport com.google.auto.value.extension.toprettystring.ToPrettyStringTest.PropertyHasToPrettyString.HasToPrettyString;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableMultimap;\nimport com.google.common.collect.Multimap;\nimport com.google.common.primitives.ImmutableIntArray;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport javax.annotation.Nullable;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@SuppressWarnings(\"AutoValueImmutableFields\")\n@RunWith(JUnit4.class)\npublic class ToPrettyStringTest {\n  @AutoValue\n  abstract static class Primitives {\n    abstract int i();\n\n    abstract long l();\n\n    abstract byte b();\n\n    abstract short s();\n\n    abstract char c();\n\n    abstract float f();\n\n    abstract double d();\n\n    abstract boolean bool();\n\n    @ToPrettyString\n    abstract String toPrettyString();\n  }\n\n  @Test\n  public void primitives() {\n    Primitives valueType =\n        new AutoValue_ToPrettyStringTest_Primitives(\n            1, 2L, (byte) 3, (short) 4, 'C', 6.6f, 7.7, false);\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"Primitives {\"\n                + \"\\n  i = 1,\"\n                + \"\\n  l = 2,\"\n                + \"\\n  b = 3,\"\n                + \"\\n  s = 4,\"\n                + \"\\n  c = C,\"\n                + \"\\n  f = 6.6,\"\n                + \"\\n  d = 7.7,\"\n                + \"\\n  bool = false,\"\n                + \"\\n}\");\n  }\n\n  @AutoValue\n  abstract static class PrimitiveArray {\n    @Nullable\n    @SuppressWarnings(\"mutable\")\n    abstract long[] longs();\n\n    @ToPrettyString\n    abstract String toPrettyString();\n  }\n\n  @Test\n  public void primitiveArray() {\n    PrimitiveArray valueType =\n        new AutoValue_ToPrettyStringTest_PrimitiveArray(new long[] {1L, 2L, 10L, 200L});\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"PrimitiveArray {\"\n                + \"\\n  longs = [\"\n                + \"\\n    1,\"\n                + \"\\n    2,\"\n                + \"\\n    10,\"\n                + \"\\n    200,\"\n                + \"\\n  ],\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void primitiveArray_empty() {\n    PrimitiveArray valueType = new AutoValue_ToPrettyStringTest_PrimitiveArray(new long[0]);\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"PrimitiveArray {\" // force newline\n                + \"\\n  longs = [],\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void primitiveArray_null() {\n    PrimitiveArray valueType = new AutoValue_ToPrettyStringTest_PrimitiveArray(null);\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"PrimitiveArray {\" // force newline\n                + \"\\n  longs = null,\"\n                + \"\\n}\");\n  }\n\n  @AutoValue\n  abstract static class PrettyCollection {\n    @Nullable\n    abstract Collection<Object> collection();\n\n    @ToPrettyString\n    abstract String toPrettyString();\n  }\n\n  @Test\n  public void prettyCollection() {\n    PrettyCollection valueType =\n        new AutoValue_ToPrettyStringTest_PrettyCollection(ImmutableList.of(\"hello\", \"world\"));\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"PrettyCollection {\"\n                + \"\\n  collection = [\"\n                + \"\\n    hello,\"\n                + \"\\n    world,\"\n                + \"\\n  ],\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void prettyCollection_elementsWithNewlines() {\n    PrettyCollection valueType =\n        new AutoValue_ToPrettyStringTest_PrettyCollection(\n            ImmutableList.of(\"hello\\nworld\\nnewline\"));\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"PrettyCollection {\"\n                + \"\\n  collection = [\"\n                + \"\\n    hello\"\n                + \"\\n    world\"\n                + \"\\n    newline,\"\n                + \"\\n  ],\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void prettyCollection_empty() {\n    PrettyCollection valueType =\n        new AutoValue_ToPrettyStringTest_PrettyCollection(ImmutableList.of());\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"PrettyCollection {\" // force newline\n                + \"\\n  collection = [],\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void prettyCollection_null() {\n    PrettyCollection valueType = new AutoValue_ToPrettyStringTest_PrettyCollection(null);\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"PrettyCollection {\" // force newline\n                + \"\\n  collection = null,\"\n                + \"\\n}\");\n  }\n\n  @AutoValue\n  abstract static class NestedCollection {\n    @Nullable\n    abstract Collection<Collection<Object>> nestedCollection();\n\n    @ToPrettyString\n    abstract String toPrettyString();\n  }\n\n  @Test\n  public void nestedCollection() {\n    NestedCollection valueType =\n        new AutoValue_ToPrettyStringTest_NestedCollection(\n            Arrays.asList(\n                ImmutableList.of(\"hello\", \"world\"),\n                ImmutableList.of(\"hello2\", \"world2\"),\n                null,\n                Arrays.asList(\"not null\", null)));\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"NestedCollection {\"\n                + \"\\n  nestedCollection = [\"\n                + \"\\n    [\"\n                + \"\\n      hello,\"\n                + \"\\n      world,\"\n                + \"\\n    ],\"\n                + \"\\n    [\"\n                + \"\\n      hello2,\"\n                + \"\\n      world2,\"\n                + \"\\n    ],\"\n                + \"\\n    null,\"\n                + \"\\n    [\"\n                + \"\\n      not null,\"\n                + \"\\n      null,\"\n                + \"\\n    ],\"\n                + \"\\n  ],\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void nestedCollection_elementsWithNewlines() {\n    NestedCollection valueType =\n        new AutoValue_ToPrettyStringTest_NestedCollection(\n            ImmutableList.of(\n                ImmutableList.of((Object) \"hello\\nworld\\nnewline\", \"hello2\\nworld2\\nnewline2\")));\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"NestedCollection {\"\n                + \"\\n  nestedCollection = [\"\n                + \"\\n    [\"\n                + \"\\n      hello\"\n                + \"\\n      world\"\n                + \"\\n      newline,\"\n                + \"\\n      hello2\"\n                + \"\\n      world2\"\n                + \"\\n      newline2,\"\n                + \"\\n    ],\"\n                + \"\\n  ],\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void nestedCollection_empty() {\n    NestedCollection valueType =\n        new AutoValue_ToPrettyStringTest_NestedCollection(ImmutableList.of());\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"NestedCollection {\" // force newline\n                + \"\\n  nestedCollection = [],\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void nestedCollection_nestedEmpty() {\n    NestedCollection valueType =\n        new AutoValue_ToPrettyStringTest_NestedCollection(\n            ImmutableList.of(ImmutableList.of(), ImmutableList.of()));\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"NestedCollection {\"\n                + \"\\n  nestedCollection = [\"\n                + \"\\n    [],\"\n                + \"\\n    [],\"\n                + \"\\n  ],\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void nestedCollection_null() {\n    NestedCollection valueType = new AutoValue_ToPrettyStringTest_NestedCollection(null);\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"NestedCollection {\" // force newline\n                + \"\\n  nestedCollection = null,\"\n                + \"\\n}\");\n  }\n\n  @AutoValue\n  abstract static class ImmutablePrimitiveArray {\n    @Nullable\n    abstract ImmutableIntArray immutableIntArray();\n\n    @ToPrettyString\n    abstract String toPrettyString();\n  }\n\n  @Test\n  public void immutablePrimitiveArray() {\n    ImmutablePrimitiveArray valueType =\n        new AutoValue_ToPrettyStringTest_ImmutablePrimitiveArray(ImmutableIntArray.of(1, 2));\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"ImmutablePrimitiveArray {\"\n                + \"\\n  immutableIntArray = [\"\n                + \"\\n    1,\"\n                + \"\\n    2,\"\n                + \"\\n  ],\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void immutablePrimitiveArray_empty() {\n    ImmutablePrimitiveArray valueType =\n        new AutoValue_ToPrettyStringTest_ImmutablePrimitiveArray(ImmutableIntArray.of());\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"ImmutablePrimitiveArray {\" // force newline\n                + \"\\n  immutableIntArray = [],\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void immutablePrimitiveArray_null() {\n    ImmutablePrimitiveArray valueType =\n        new AutoValue_ToPrettyStringTest_ImmutablePrimitiveArray(null);\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"ImmutablePrimitiveArray {\" // force newline\n                + \"\\n  immutableIntArray = null,\"\n                + \"\\n}\");\n  }\n\n  @AutoValue\n  abstract static class PrettyMap {\n    @Nullable\n    abstract Map<Object, Object> map();\n\n    @ToPrettyString\n    abstract String toPrettyString();\n  }\n\n  @Test\n  public void prettyMap() {\n    PrettyMap valueType = new AutoValue_ToPrettyStringTest_PrettyMap(ImmutableMap.of(1, 2));\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"PrettyMap {\" // force newline\n                + \"\\n  map = {\"\n                + \"\\n    1: 2,\"\n                + \"\\n  },\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void prettyMap_keysAndValuesWithNewlines() {\n    PrettyMap valueType =\n        new AutoValue_ToPrettyStringTest_PrettyMap(\n            ImmutableMap.of(\n                \"key1\\nnewline\", \"value1\\nnewline\", \"key2\\nnewline\", \"value2\\nnewline\"));\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"PrettyMap {\"\n                + \"\\n  map = {\"\n                + \"\\n    key1\"\n                + \"\\n    newline: value1\"\n                + \"\\n    newline,\"\n                + \"\\n    key2\"\n                + \"\\n    newline: value2\"\n                + \"\\n    newline,\"\n                + \"\\n  },\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void prettyMap_empty() {\n    PrettyMap valueType = new AutoValue_ToPrettyStringTest_PrettyMap(ImmutableMap.of());\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"PrettyMap {\" // force newline\n                + \"\\n  map = {},\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void prettyMap_null() {\n    PrettyMap valueType = new AutoValue_ToPrettyStringTest_PrettyMap(null);\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"PrettyMap {\" // force newline\n                + \"\\n  map = null,\"\n                + \"\\n}\");\n  }\n\n  @AutoValue\n  abstract static class MapOfMaps {\n    @Nullable\n    abstract Map<Map<Object, Object>, Map<Object, Object>> mapOfMaps();\n\n    @ToPrettyString\n    abstract String toPrettyString();\n  }\n\n  private static <K, V> Map<K, V> mapWithNulls(K k, V v) {\n    Map<K, V> map = new LinkedHashMap<>();\n    map.put(k, v);\n    return map;\n  }\n\n  @Test\n  public void mapOfMaps() {\n    Map<Map<Object, Object>, Map<Object, Object>> mapOfMaps = new LinkedHashMap<>();\n    mapOfMaps.put(ImmutableMap.of(\"k1_k\", \"k1_v\"), ImmutableMap.of(\"v1_k\", \"v1_v\"));\n    mapOfMaps.put(ImmutableMap.of(\"k2_k\", \"k2_v\"), ImmutableMap.of(\"v2_k\", \"v2_v\"));\n    mapOfMaps.put(mapWithNulls(\"keyForNullValue\", null), mapWithNulls(null, \"valueForNullKey\"));\n    mapOfMaps.put(null, ImmutableMap.of(\"nullKeyKey\", \"nullKeyValue\"));\n    mapOfMaps.put(ImmutableMap.of(\"nullValueKey\", \"nullValueValue\"), null);\n    mapOfMaps.put(\n        ImmutableMap.of(\"keyForMapOfNullsKey\", \"keyForMapOfNullsValue\"), mapWithNulls(null, null));\n    MapOfMaps valueType = new AutoValue_ToPrettyStringTest_MapOfMaps(mapOfMaps);\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"MapOfMaps {\"\n                + \"\\n  mapOfMaps = {\"\n                + \"\\n    {\"\n                + \"\\n      k1_k: k1_v,\"\n                + \"\\n    }: {\"\n                + \"\\n      v1_k: v1_v,\"\n                + \"\\n    },\"\n                + \"\\n    {\"\n                + \"\\n      k2_k: k2_v,\"\n                + \"\\n    }: {\"\n                + \"\\n      v2_k: v2_v,\"\n                + \"\\n    },\"\n                + \"\\n    {\"\n                + \"\\n      keyForNullValue: null,\"\n                + \"\\n    }: {\"\n                + \"\\n      null: valueForNullKey,\"\n                + \"\\n    },\"\n                + \"\\n    null: {\"\n                + \"\\n      nullKeyKey: nullKeyValue,\"\n                + \"\\n    },\"\n                + \"\\n    {\"\n                + \"\\n      nullValueKey: nullValueValue,\"\n                + \"\\n    }: null,\"\n                + \"\\n    {\"\n                + \"\\n      keyForMapOfNullsKey: keyForMapOfNullsValue,\"\n                + \"\\n    }: {\"\n                + \"\\n      null: null,\"\n                + \"\\n    },\"\n                + \"\\n  },\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void mapOfMaps_elementsWithNewlines() {\n    MapOfMaps valueType =\n        new AutoValue_ToPrettyStringTest_MapOfMaps(\n            ImmutableMap.of(\n                ImmutableMap.of((Object) \"k_k\\nnewline\", (Object) \"k_v\\nnewline\"),\n                ImmutableMap.of((Object) \"v_k\\nnewline\", (Object) \"v_v\\nnewline\")));\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"MapOfMaps {\"\n                + \"\\n  mapOfMaps = {\"\n                + \"\\n    {\"\n                + \"\\n      k_k\"\n                + \"\\n      newline: k_v\"\n                + \"\\n      newline,\"\n                + \"\\n    }: {\"\n                + \"\\n      v_k\"\n                + \"\\n      newline: v_v\"\n                + \"\\n      newline,\"\n                + \"\\n    },\"\n                + \"\\n  },\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void mapOfMaps_empty() {\n    MapOfMaps valueType = new AutoValue_ToPrettyStringTest_MapOfMaps(ImmutableMap.of());\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"MapOfMaps {\" // force newline\n                + \"\\n  mapOfMaps = {},\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void mapOfMaps_nestedEmpty() {\n    MapOfMaps valueType =\n        new AutoValue_ToPrettyStringTest_MapOfMaps(\n            ImmutableMap.of(ImmutableMap.of(), ImmutableMap.of()));\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"MapOfMaps {\" // force newline\n                + \"\\n  mapOfMaps = {\"\n                + \"\\n    {}: {},\"\n                + \"\\n  },\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void mapOfMaps_null() {\n    MapOfMaps valueType = new AutoValue_ToPrettyStringTest_MapOfMaps(null);\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"MapOfMaps {\" // force newline\n                + \"\\n  mapOfMaps = null,\"\n                + \"\\n}\");\n  }\n\n  @AutoValue\n  abstract static class PrettyMultimap {\n    @Nullable\n    abstract Multimap<Object, Object> multimap();\n\n    @ToPrettyString\n    abstract String toPrettyString();\n  }\n\n  @Test\n  public void prettyMultimap() {\n    PrettyMultimap valueType =\n        new AutoValue_ToPrettyStringTest_PrettyMultimap(\n            ImmutableMultimap.builder().putAll(\"k\", \"v1\", \"v2\").build());\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"PrettyMultimap {\" // force newline\n                + \"\\n  multimap = {\"\n                + \"\\n    k: [\"\n                + \"\\n      v1,\"\n                + \"\\n      v2,\"\n                + \"\\n    ],\"\n                + \"\\n  },\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void prettyMultimap_keysAndValuesWithNewlines() {\n    PrettyMultimap valueType =\n        new AutoValue_ToPrettyStringTest_PrettyMultimap(\n            ImmutableMultimap.builder()\n                .putAll(\"key\\nnewline\", \"value1\\nnewline\", \"value2\\nnewline\")\n                .build());\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"PrettyMultimap {\"\n                + \"\\n  multimap = {\"\n                + \"\\n    key\"\n                + \"\\n    newline: [\"\n                + \"\\n      value1\"\n                + \"\\n      newline,\"\n                + \"\\n      value2\"\n                + \"\\n      newline,\"\n                + \"\\n    ],\"\n                + \"\\n  },\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void prettyMultimap_empty() {\n    PrettyMultimap valueType =\n        new AutoValue_ToPrettyStringTest_PrettyMultimap(ImmutableMultimap.of());\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"PrettyMultimap {\" // force newline\n                + \"\\n  multimap = {},\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void prettyMultimap_null() {\n    PrettyMultimap valueType = new AutoValue_ToPrettyStringTest_PrettyMultimap(null);\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"PrettyMultimap {\" // force newline\n                + \"\\n  multimap = null,\"\n                + \"\\n}\");\n  }\n\n  @AutoValue\n  abstract static class JavaOptional {\n    @Nullable\n    abstract java.util.Optional<Object> optional();\n\n    @ToPrettyString\n    abstract String toPrettyString();\n  }\n\n  @Test\n  public void javaOptional_present() {\n    JavaOptional valueType =\n        new AutoValue_ToPrettyStringTest_JavaOptional(java.util.Optional.of(\"hello, world\"));\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"JavaOptional {\" // force newline\n                + \"\\n  optional = hello, world,\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void javaOptional_empty() {\n    JavaOptional valueType =\n        new AutoValue_ToPrettyStringTest_JavaOptional(java.util.Optional.empty());\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"JavaOptional {\" // force newline\n                + \"\\n  optional = <empty>,\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void javaOptional_valueWithNewlines() {\n    JavaOptional valueType =\n        new AutoValue_ToPrettyStringTest_JavaOptional(\n            java.util.Optional.of(\"optional\\nwith\\nnewline\"));\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"JavaOptional {\" // force newline\n                + \"\\n  optional = optional\"\n                + \"\\n  with\"\n                + \"\\n  newline,\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void javaOptional_null() {\n    @SuppressWarnings(\"NullOptional\")\n    JavaOptional valueType = new AutoValue_ToPrettyStringTest_JavaOptional(null);\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"JavaOptional {\" // force newline\n                + \"\\n  optional = null,\"\n                + \"\\n}\");\n  }\n\n  @AutoValue\n  abstract static class GuavaOptional {\n    @Nullable\n    abstract com.google.common.base.Optional<Object> optional();\n\n    @ToPrettyString\n    abstract String toPrettyString();\n  }\n\n  @Test\n  public void guavaOptional_present() {\n    GuavaOptional valueType =\n        new AutoValue_ToPrettyStringTest_GuavaOptional(\n            com.google.common.base.Optional.of(\"hello, world\"));\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"GuavaOptional {\" // force newline\n                + \"\\n  optional = hello, world,\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void guavaOptional_absent() {\n    GuavaOptional valueType =\n        new AutoValue_ToPrettyStringTest_GuavaOptional(com.google.common.base.Optional.absent());\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"GuavaOptional {\" // force newline\n                + \"\\n  optional = <absent>,\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void guavaOptional_valueWithNewlines() {\n    GuavaOptional valueType =\n        new AutoValue_ToPrettyStringTest_GuavaOptional(\n            com.google.common.base.Optional.of(\"optional\\nwith\\nnewline\"));\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"GuavaOptional {\" // force newline\n                + \"\\n  optional = optional\"\n                + \"\\n  with\"\n                + \"\\n  newline,\"\n                + \"\\n}\");\n  }\n\n  @Test\n  public void guavaOptional_null() {\n    @SuppressWarnings(\"NullOptional\")\n    GuavaOptional valueType = new AutoValue_ToPrettyStringTest_GuavaOptional(null);\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"GuavaOptional {\" // force newline\n                + \"\\n  optional = null,\"\n                + \"\\n}\");\n  }\n\n  @AutoValue\n  abstract static class NestAllTheThings {\n    @Nullable\n    abstract com.google.common.base.Optional<\n            java.util.Optional<\n                List< // open list\n                    Map<ImmutableIntArray, Multimap<int[][], Object>>\n                // close list\n                >>>\n        value();\n\n    @ToPrettyString\n    abstract String toPrettyString();\n  }\n\n  @Test\n  public void nestAllTheThings() {\n    NestAllTheThings valueType =\n        new AutoValue_ToPrettyStringTest_NestAllTheThings(\n            com.google.common.base.Optional.of(\n                java.util.Optional.of(\n                    ImmutableList.of(\n                        ImmutableMap.of(\n                            ImmutableIntArray.of(-1, -2, -3),\n                            ImmutableMultimap.of(\n                                new int[][] {{1, 2}, {3, 4, 5}, {}}, \"value\\nwith\\nnewline\"))))));\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"NestAllTheThings {\"\n                + \"\\n  value = [\"\n                + \"\\n    {\"\n                + \"\\n      [\"\n                + \"\\n        -1,\"\n                + \"\\n        -2,\"\n                + \"\\n        -3,\"\n                + \"\\n      ]: {\"\n                + \"\\n        [\"\n                + \"\\n          [\"\n                + \"\\n            1,\"\n                + \"\\n            2,\"\n                + \"\\n          ],\"\n                + \"\\n          [\"\n                + \"\\n            3,\"\n                + \"\\n            4,\"\n                + \"\\n            5,\"\n                + \"\\n          ],\"\n                + \"\\n          [],\"\n                + \"\\n        ]: [\"\n                + \"\\n          value\"\n                + \"\\n          with\"\n                + \"\\n          newline,\"\n                + \"\\n        ],\"\n                + \"\\n      },\"\n                + \"\\n    },\"\n                + \"\\n  ],\"\n                + \"\\n}\");\n  }\n\n  @AutoValue\n  abstract static class WithCustomName {\n    abstract int i();\n\n    @ToPrettyString\n    abstract String customName();\n  }\n\n  @Test\n  public void withCustomName() {\n    WithCustomName valueType = new AutoValue_ToPrettyStringTest_WithCustomName(1);\n\n    assertThat(valueType.customName())\n        .isEqualTo(\n            \"WithCustomName {\" // force newline\n                + \"\\n  i = 1,\"\n                + \"\\n}\");\n  }\n\n  @AutoValue\n  abstract static class OverridesToString {\n    abstract int i();\n\n    @ToPrettyString\n    @Override\n    public abstract String toString();\n  }\n\n  @Test\n  public void overridesToString() {\n    OverridesToString valueType = new AutoValue_ToPrettyStringTest_OverridesToString(1);\n\n    assertThat(valueType.toString())\n        .isEqualTo(\n            \"OverridesToString {\" // force newline\n                + \"\\n  i = 1,\"\n                + \"\\n}\");\n  }\n\n  @AutoValue\n  abstract static class PropertyHasToPrettyString {\n    static class HasToPrettyString<A> {\n      @Override\n      public String toString() {\n        throw new AssertionError();\n      }\n\n      @ToPrettyString\n      String toPrettyString() {\n        return \"custom\\n@ToPrettyString\\nmethod\";\n      }\n    }\n\n    static class HasInheritedToPrettyString extends HasToPrettyString<String> {}\n\n    interface HasToPrettyStringInInterface {\n      @ToPrettyString\n      default String toPrettyString() {\n        return \"custom\\n@ToPrettyString\\nmethod\\ninterface\";\n      }\n    }\n\n    static class HasToPrettyStringFromSuperInterface implements HasToPrettyStringInInterface {}\n\n    abstract HasToPrettyString<String> parameterizedWithString();\n\n    abstract HasToPrettyString<Void> parameterizedWithVoid();\n\n    abstract HasInheritedToPrettyString superclass();\n\n    abstract HasToPrettyStringFromSuperInterface superinterface();\n\n    @ToPrettyString\n    abstract String toPrettyString();\n  }\n\n  @Test\n  public void propertyHasToPrettyString() {\n    PropertyHasToPrettyString valueType =\n        new AutoValue_ToPrettyStringTest_PropertyHasToPrettyString(\n            new PropertyHasToPrettyString.HasToPrettyString<>(),\n            new PropertyHasToPrettyString.HasToPrettyString<>(),\n            new PropertyHasToPrettyString.HasInheritedToPrettyString(),\n            new PropertyHasToPrettyString.HasToPrettyStringFromSuperInterface());\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"PropertyHasToPrettyString {\"\n                + \"\\n  parameterizedWithString = custom\"\n                + \"\\n  @ToPrettyString\"\n                + \"\\n  method,\"\n                + \"\\n  parameterizedWithVoid = custom\"\n                + \"\\n  @ToPrettyString\"\n                + \"\\n  method,\"\n                + \"\\n  superclass = custom\"\n                + \"\\n  @ToPrettyString\"\n                + \"\\n  method,\"\n                + \"\\n  superinterface = custom\"\n                + \"\\n  @ToPrettyString\"\n                + \"\\n  method\"\n                + \"\\n  interface,\"\n                + \"\\n}\");\n  }\n\n  @AutoValue\n  abstract static class CollectionSubtypesWithFixedTypeParameters {\n    static class StringList extends ArrayList<String> {}\n\n    static class StringMap extends LinkedHashMap<String, String> {}\n\n    abstract StringList list();\n\n    abstract StringMap map();\n\n    @ToPrettyString\n    abstract String toPrettyString();\n  }\n\n  @Test\n  public void fixedTypeParameters() {\n    StringList stringList = new StringList();\n    stringList.addAll(ImmutableList.of(\"a\", \"b\", \"c\"));\n    StringMap stringMap = new StringMap();\n    stringMap.putAll(ImmutableMap.of(\"A\", \"a\", \"B\", \"b\"));\n    CollectionSubtypesWithFixedTypeParameters valueType =\n        new AutoValue_ToPrettyStringTest_CollectionSubtypesWithFixedTypeParameters(\n            stringList, stringMap);\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"CollectionSubtypesWithFixedTypeParameters {\"\n                + \"\\n  list = [\"\n                + \"\\n    a,\"\n                + \"\\n    b,\"\n                + \"\\n    c,\"\n                + \"\\n  ],\"\n                + \"\\n  map = {\"\n                + \"\\n    A: a,\"\n                + \"\\n    B: b,\"\n                + \"\\n  },\"\n                + \"\\n}\");\n  }\n\n  @AutoValue\n  abstract static class JavaBeans {\n    abstract int getInt();\n\n    abstract boolean isBoolean();\n\n    abstract String getNotAJavaIdentifier();\n\n    @ToPrettyString\n    abstract String toPrettyString();\n  }\n\n  @Test\n  public void javaBeans() {\n    JavaBeans valueType = new AutoValue_ToPrettyStringTest_JavaBeans(4, false, \"not\");\n\n    assertThat(valueType.toPrettyString())\n        .isEqualTo(\n            \"JavaBeans {\"\n                + \"\\n  int = 4,\"\n                + \"\\n  boolean = false,\"\n                + \"\\n  notAJavaIdentifier = not,\"\n                + \"\\n}\");\n\n    // Check to make sure that we use the same property names that AutoValue does. This is mostly\n    // defensive, since in some scenarios AutoValue considers the property names of a java bean as\n    // having the prefix removed.\n    assertThat(valueType.toString())\n        .isEqualTo(\"JavaBeans{int=4, boolean=false, notAJavaIdentifier=not}\");\n  }\n\n  @AutoValue\n  abstract static class Generic<T> {\n    abstract T get();\n\n    @ToPrettyString\n    abstract String toPrettyString();\n  }\n\n  @Test\n  public void generic() {\n    Generic<String> valueType = new AutoValue_ToPrettyStringTest_Generic<>(\"hello\");\n\n    assertThat(valueType.toPrettyString()).isEqualTo(\"Generic {\\n  get = hello,\\n}\");\n\n    // Check to make sure that we use the same property names that AutoValue does. This is mostly\n    // defensive, since in some scenarios AutoValue considers the property names of a java bean as\n    // having the prefix removed.\n    assertThat(valueType.toString()).isEqualTo(\"Generic{get=hello}\");\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/extension/toprettystring/ToPrettyStringValidatorTest.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.auto.value.extension.toprettystring;\n\nimport static com.google.testing.compile.CompilationSubject.assertThat;\nimport static com.google.testing.compile.Compiler.javac;\n\nimport com.google.auto.value.extension.toprettystring.processor.ToPrettyStringValidator;\nimport com.google.testing.compile.Compilation;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic class ToPrettyStringValidatorTest {\n  @Test\n  public void cannotBeStatic() {\n    JavaFileObject file =\n        JavaFileObjects.forSourceLines(\n            \"test.Test\",\n            \"package test;\",\n            \"\",\n            \"import com.google.auto.value.extension.toprettystring.ToPrettyString;\",\n            \"\",\n            \"class Test {\",\n            \"  @ToPrettyString\",\n            \"  static String toPretty() {\",\n            \"   return new String();\",\n            \"  }\",\n            \"}\",\n            \"\");\n    Compilation compilation = compile(file);\n\n    assertThat(compilation).failed();\n    assertThat(compilation).hadErrorCount(1);\n    assertThat(compilation)\n        .hadErrorContaining(\"must be instance methods\")\n        .inFile(file)\n        .onLineContaining(\"static String toPretty()\");\n  }\n\n  @Test\n  public void mustReturnString() {\n    JavaFileObject file =\n        JavaFileObjects.forSourceLines(\n            \"test.Test\",\n            \"package test;\",\n            \"\",\n            \"import com.google.auto.value.extension.toprettystring.ToPrettyString;\",\n            \"\",\n            \"class Test {\",\n            \"  @ToPrettyString\",\n            \"  CharSequence toPretty() {\",\n            \"   return new String();\",\n            \"  }\",\n            \"}\",\n            \"\");\n    Compilation compilation = compile(file);\n\n    assertThat(compilation).failed();\n    assertThat(compilation).hadErrorCount(1);\n    assertThat(compilation)\n        .hadErrorContaining(\"must return String\")\n        .inFile(file)\n        .onLineContaining(\"CharSequence toPretty()\");\n  }\n\n  @Test\n  public void noParameters() {\n    JavaFileObject file =\n        JavaFileObjects.forSourceLines(\n            \"test.Test\",\n            \"package test;\",\n            \"\",\n            \"import com.google.auto.value.extension.toprettystring.ToPrettyString;\",\n            \"\",\n            \"class Test {\",\n            \"  @ToPrettyString\",\n            \"  String toPretty(String value) {\",\n            \"   return value;\",\n            \"  }\",\n            \"}\",\n            \"\");\n    Compilation compilation = compile(file);\n\n    assertThat(compilation).failed();\n    assertThat(compilation).hadErrorCount(1);\n    assertThat(compilation)\n        .hadErrorContaining(\"cannot have parameters\")\n        .inFile(file)\n        .onLineContaining(\"String toPretty(String value)\");\n  }\n\n  @Test\n  public void onlyOneToPrettyStringMethod_sameClass() {\n    JavaFileObject file =\n        JavaFileObjects.forSourceLines(\n            \"test.Test\",\n            \"package test;\",\n            \"\",\n            \"import com.google.auto.value.extension.toprettystring.ToPrettyString;\",\n            \"\",\n            \"class Test {\",\n            \"  @ToPrettyString\",\n            \"  String toPretty1() {\",\n            \"   return new String();\",\n            \"  }\",\n            \"\",\n            \"  @ToPrettyString\",\n            \"  String toPretty2() {\",\n            \"   return new String();\",\n            \"  }\",\n            \"}\",\n            \"\");\n    Compilation compilation = compile(file);\n\n    assertThat(compilation).failed();\n    assertThat(compilation).hadErrorCount(1);\n    assertThat(compilation)\n        .hadErrorContaining(\n            error(\n                \"test.Test has multiple @ToPrettyString methods:\",\n                \"  - test.Test.toPretty1()\",\n                \"  - test.Test.toPretty2()\"))\n        .inFile(file)\n        .onLineContaining(\"class Test\");\n  }\n\n  @Test\n  public void onlyOneToPrettyStringMethod_superclass() {\n    JavaFileObject superclass =\n        JavaFileObjects.forSourceLines(\n            \"test.Superclass\",\n            \"package test;\",\n            \"\",\n            \"import com.google.auto.value.extension.toprettystring.ToPrettyString;\",\n            \"\",\n            \"class Superclass {\",\n            \"  @ToPrettyString\",\n            \"  String toPretty1() {\",\n            \"   return new String();\",\n            \"  }\",\n            \"}\",\n            \"\");\n    JavaFileObject subclass =\n        JavaFileObjects.forSourceLines(\n            \"test.Subclass\",\n            \"package test;\",\n            \"\",\n            \"import com.google.auto.value.extension.toprettystring.ToPrettyString;\",\n            \"\",\n            \"class Subclass extends Superclass {\",\n            \"  @ToPrettyString\",\n            \"  String toPretty2() {\",\n            \"   return new String();\",\n            \"  }\",\n            \"}\",\n            \"\");\n    Compilation compilation = compile(superclass, subclass);\n\n    assertThat(compilation).failed();\n    assertThat(compilation).hadErrorCount(1);\n    assertThat(compilation)\n        .hadErrorContaining(\n            error(\n                \"test.Subclass has multiple @ToPrettyString methods:\",\n                \"  - test.Superclass.toPretty1()\",\n                \"  - test.Subclass.toPretty2()\"))\n        .inFile(subclass)\n        .onLineContaining(\"class Subclass\");\n  }\n\n  @Test\n  public void onlyOneToPrettyStringMethod_superinterface() {\n    JavaFileObject superinterface =\n        JavaFileObjects.forSourceLines(\n            \"test.Superinterface\",\n            \"package test;\",\n            \"\",\n            \"import com.google.auto.value.extension.toprettystring.ToPrettyString;\",\n            \"\",\n            \"interface Superinterface {\",\n            \"  @ToPrettyString\",\n            \"  default String toPretty1() {\",\n            \"   return new String();\",\n            \"  }\",\n            \"}\",\n            \"\");\n    JavaFileObject subclass =\n        JavaFileObjects.forSourceLines(\n            \"test.Subclass\",\n            \"package test;\",\n            \"\",\n            \"import com.google.auto.value.extension.toprettystring.ToPrettyString;\",\n            \"\",\n            \"class Subclass implements Superinterface {\",\n            \"  @ToPrettyString\",\n            \"  String toPretty2() {\",\n            \"   return new String();\",\n            \"  }\",\n            \"}\",\n            \"\");\n    Compilation compilation = compile(superinterface, subclass);\n\n    assertThat(compilation).failed();\n    assertThat(compilation).hadErrorCount(1);\n    assertThat(compilation)\n        .hadErrorContaining(\n            error(\n                \"test.Subclass has multiple @ToPrettyString methods:\",\n                \"  - test.Superinterface.toPretty1()\",\n                \"  - test.Subclass.toPretty2()\"))\n        .inFile(subclass)\n        .onLineContaining(\"class Subclass\");\n  }\n\n  private static Compilation compile(JavaFileObject... javaFileObjects) {\n    return javac().withProcessors(new ToPrettyStringValidator()).compile(javaFileObjects);\n  }\n\n  private static String error(String... lines) {\n    return String.join(\"\\n  \", lines);\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/AutoAnnotationCompilationTest.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.testing.compile.CompilationSubject.assertThat;\nimport static com.google.testing.compile.Compiler.javac;\n\nimport com.google.testing.compile.Compilation;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class AutoAnnotationCompilationTest {\n\n  @Test\n  public void testSimple() {\n    JavaFileObject myAnnotationJavaFile =\n        JavaFileObjects.forSourceLines(\n            \"com.example.annotations.MyAnnotation\",\n            \"package com.example.annotations;\",\n            \"\",\n            \"import com.example.enums.MyEnum;\",\n            \"\",\n            \"public @interface MyAnnotation {\",\n            \"  MyEnum value();\",\n            \"  int defaultedValue() default 23;\",\n            \"}\");\n    int invariableHash = (\"defaultedValue\".hashCode() * 127) ^ 23;\n    JavaFileObject myEnumJavaFile =\n        JavaFileObjects.forSourceLines(\n            \"com.example.enums.MyEnum\",\n            \"package com.example.enums;\",\n            \"\",\n            \"public enum MyEnum {\",\n            \"  ONE\",\n            \"}\");\n    JavaFileObject annotationFactoryJavaFile =\n        JavaFileObjects.forSourceLines(\n            \"com.example.factories.AnnotationFactory\",\n            \"package com.example.factories;\",\n            \"\",\n            \"import com.google.auto.value.AutoAnnotation;\",\n            \"import com.example.annotations.MyAnnotation;\",\n            \"import com.example.enums.MyEnum;\",\n            \"\",\n            \"public class AnnotationFactory {\",\n            \"  @AutoAnnotation\",\n            \"  public static MyAnnotation newMyAnnotation(MyEnum value) {\",\n            \"    return new AutoAnnotation_AnnotationFactory_newMyAnnotation(value);\",\n            \"  }\",\n            \"}\");\n    JavaFileObject expectedOutput =\n        JavaFileObjects.forSourceLines(\n            \"com.example.factories.AutoAnnotation_AnnotationFactory_newMyAnnotation\",\n            \"package com.example.factories;\",\n            \"\",\n            \"import com.example.annotations.MyAnnotation;\",\n            \"import com.example.enums.MyEnum;\",\n            \"import java.io.Serializable;\",\n            GeneratedImport.importGeneratedAnnotationType(),\n            \"\",\n            \"@Generated(\\\"\" + AutoAnnotationProcessor.class.getName() + \"\\\")\",\n            \"final class AutoAnnotation_AnnotationFactory_newMyAnnotation\",\n            \"     implements MyAnnotation, Serializable {\",\n            \"  private static final long serialVersionUID = -7473814294717163169L;\",\n            \"  private final MyEnum value;\",\n            \"  private static final int defaultedValue = 23;\",\n            \"\",\n            \"  AutoAnnotation_AnnotationFactory_newMyAnnotation(MyEnum value) {\",\n            \"    if (value == null) {\",\n            \"      throw new NullPointerException(\\\"Null value\\\");\",\n            \"    }\",\n            \"    this.value = value;\",\n            \"  }\",\n            \"\",\n            \"  @Override public Class<? extends MyAnnotation> annotationType() {\",\n            \"    return MyAnnotation.class;\",\n            \"  }\",\n            \"\",\n            \"  @Override public MyEnum value() {\",\n            \"    return value;\",\n            \"  }\",\n            \"\",\n            \"  @Override public int defaultedValue() {\",\n            \"    return defaultedValue;\",\n            \"  }\",\n            \"\",\n            \"  @Override public String toString() {\",\n            \"    StringBuilder sb = new StringBuilder(\\\"@com.example.annotations.MyAnnotation(\\\");\",\n            \"    sb.append(value);\",\n            \"    return sb.append(')').toString();\",\n            \"  }\",\n            \"\",\n            \"  @Override public boolean equals(Object o) {\",\n            \"    if (o == this) {\",\n            \"      return true;\",\n            \"    }\",\n            \"    if (o instanceof MyAnnotation) {\",\n            \"      MyAnnotation that = (MyAnnotation) o;\",\n            \"      return value.equals(that.value())\",\n            \"          && (defaultedValue == that.defaultedValue());\",\n            \"    }\",\n            \"    return false;\",\n            \"  }\",\n            \"\",\n            \"  @Override public int hashCode() {\",\n            \"    return \",\n            \"        \" + invariableHash,\n            \"        + (\" + 127 * \"value\".hashCode() + \" ^ value.hashCode())\",\n            \"    ;\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoAnnotationProcessor())\n            .withOptions(\"-A\" + Nullables.NULLABLE_OPTION + \"=\")\n            .compile(annotationFactoryJavaFile, myAnnotationJavaFile, myEnumJavaFile);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\n            \"com.example.factories.AutoAnnotation_AnnotationFactory_newMyAnnotation\")\n        .hasSourceEquivalentTo(expectedOutput);\n  }\n\n  @Test\n  public void testEmptyPackage() {\n    JavaFileObject myAnnotationJavaFile =\n        JavaFileObjects.forSourceLines(\n            \"MyAnnotation\", //\n            \"public @interface MyAnnotation {}\");\n    JavaFileObject annotationFactoryJavaFile =\n        JavaFileObjects.forSourceLines(\n            \"AnnotationFactory\",\n            \"import com.google.auto.value.AutoAnnotation;\",\n            \"\",\n            \"public class AnnotationFactory {\",\n            \"  @AutoAnnotation\",\n            \"  public static MyAnnotation newMyAnnotation() {\",\n            \"    return new AutoAnnotation_AnnotationFactory_newMyAnnotation();\",\n            \"  }\",\n            \"}\");\n    JavaFileObject expectedOutput =\n        JavaFileObjects.forSourceLines(\n            \"AutoAnnotation_AnnotationFactory_newMyAnnotation\",\n            \"import java.io.Serializable;\",\n            GeneratedImport.importGeneratedAnnotationType(),\n            \"\",\n            \"@Generated(\\\"\" + AutoAnnotationProcessor.class.getName() + \"\\\")\",\n            \"final class AutoAnnotation_AnnotationFactory_newMyAnnotation\",\n            \"    implements MyAnnotation, Serializable {\",\n            \"  private static final long serialVersionUID = 0L;\",\n            \"  AutoAnnotation_AnnotationFactory_newMyAnnotation() {\",\n            \"  }\",\n            \"\",\n            \"  @Override public Class<? extends MyAnnotation> annotationType() {\",\n            \"    return MyAnnotation.class;\",\n            \"  }\",\n            \"\",\n            \"  @Override public String toString() {\",\n            \"    StringBuilder sb = new StringBuilder(\\\"@MyAnnotation(\\\");\",\n            \"    return sb.append(')').toString();\",\n            \"  }\",\n            \"\",\n            \"  @Override public boolean equals(Object o) {\",\n            \"    if (o == this) {\",\n            \"      return true;\",\n            \"    }\",\n            \"    if (o instanceof MyAnnotation) {\",\n            \"      return true;\",\n            \"    }\",\n            \"    return false;\",\n            \"  }\",\n            \"\",\n            \"  @Override public int hashCode() {\",\n            \"    return 0;\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoAnnotationProcessor())\n            .withOptions(\"-A\" + Nullables.NULLABLE_OPTION + \"=\")\n            .compile(annotationFactoryJavaFile, myAnnotationJavaFile);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"AutoAnnotation_AnnotationFactory_newMyAnnotation\")\n        .hasSourceEquivalentTo(expectedOutput);\n  }\n\n  @Test\n  public void testGwtSimple() {\n    JavaFileObject myAnnotationJavaFile =\n        JavaFileObjects.forSourceLines(\n            \"com.example.annotations.MyAnnotation\",\n            \"package com.example.annotations;\",\n            \"\",\n            \"import com.google.common.annotations.GwtCompatible;\",\n            \"\",\n            \"@GwtCompatible\",\n            \"public @interface MyAnnotation {\",\n            \"  int[] value();\",\n            \"}\");\n    JavaFileObject gwtCompatibleJavaFile =\n        JavaFileObjects.forSourceLines(\n            \"com.google.common.annotations.GwtCompatible\",\n            \"package com.google.common.annotations;\",\n            \"\",\n            \"public @interface GwtCompatible {}\");\n    JavaFileObject annotationFactoryJavaFile =\n        JavaFileObjects.forSourceLines(\n            \"com.example.factories.AnnotationFactory\",\n            \"package com.example.factories;\",\n            \"\",\n            \"import com.google.auto.value.AutoAnnotation;\",\n            \"import com.example.annotations.MyAnnotation;\",\n            \"\",\n            \"public class AnnotationFactory {\",\n            \"  @AutoAnnotation\",\n            \"  public static MyAnnotation newMyAnnotation(int[] value) {\",\n            \"    return new AutoAnnotation_AnnotationFactory_newMyAnnotation(value);\",\n            \"  }\",\n            \"}\");\n    JavaFileObject expectedOutput =\n        JavaFileObjects.forSourceLines(\n            \"com.example.factories.AutoAnnotation_AnnotationFactory_newMyAnnotation\",\n            \"package com.example.factories;\",\n            \"\",\n            \"import com.example.annotations.MyAnnotation;\",\n            \"import java.io.Serializable;\",\n            \"import java.util.Arrays;\",\n            GeneratedImport.importGeneratedAnnotationType(),\n            \"\",\n            \"@Generated(\\\"\" + AutoAnnotationProcessor.class.getName() + \"\\\")\",\n            \"final class AutoAnnotation_AnnotationFactory_newMyAnnotation implements MyAnnotation,\"\n                + \" Serializable {\",\n            \"  private static final long serialVersionUID = -8116050813861599066L;\",\n            \"  private final int[] value;\",\n            \"\",\n            \"  AutoAnnotation_AnnotationFactory_newMyAnnotation(int[] value) {\",\n            \"    if (value == null) {\",\n            \"      throw new NullPointerException(\\\"Null value\\\");\",\n            \"    }\",\n            \"    this.value = Arrays.copyOf(value, value.length);\",\n            \"  }\",\n            \"\",\n            \"  @Override public Class<? extends MyAnnotation> annotationType() {\",\n            \"    return MyAnnotation.class;\",\n            \"  }\",\n            \"\",\n            \"  @Override public int[] value() {\",\n            \"    return Arrays.copyOf(value, value.length);\",\n            \"  }\",\n            \"\",\n            \"  @Override public String toString() {\",\n            \"    StringBuilder sb = new StringBuilder(\\\"@com.example.annotations.MyAnnotation(\\\");\",\n            \"    sb.append(Arrays.toString(value));\",\n            \"    return sb.append(')').toString();\",\n            \"  }\",\n            \"\",\n            \"  @Override public boolean equals(Object o) {\",\n            \"    if (o == this) {\",\n            \"      return true;\",\n            \"    }\",\n            \"    if (o instanceof MyAnnotation) {\",\n            \"      MyAnnotation that = (MyAnnotation) o;\",\n            \"      return Arrays.equals(value,\",\n            \"          (that instanceof AutoAnnotation_AnnotationFactory_newMyAnnotation)\",\n            \"              ? ((AutoAnnotation_AnnotationFactory_newMyAnnotation) that).value\",\n            \"              : that.value());\",\n            \"    }\",\n            \"    return false;\",\n            \"  }\",\n            \"\",\n            \"  @Override public int hashCode() {\",\n            \"    return \",\n            \"        + (\" + 127 * \"value\".hashCode() + \" ^ Arrays.hashCode(value));\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoAnnotationProcessor())\n            .withOptions(\"-A\" + Nullables.NULLABLE_OPTION + \"=\")\n            .compile(annotationFactoryJavaFile, myAnnotationJavaFile, gwtCompatibleJavaFile);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\n            \"com.example.factories.AutoAnnotation_AnnotationFactory_newMyAnnotation\")\n        .hasSourceEquivalentTo(expectedOutput);\n  }\n\n  @Test\n  public void testCollectionsForArrays() {\n    JavaFileObject myAnnotationJavaFile =\n        JavaFileObjects.forSourceLines(\n            \"com.example.annotations.MyAnnotation\",\n            \"package com.example.annotations;\",\n            \"\",\n            \"import com.example.enums.MyEnum;\",\n            \"\",\n            \"public @interface MyAnnotation {\",\n            \"  int[] value();\",\n            \"  MyEnum[] enums() default {};\",\n            \"}\");\n    JavaFileObject myEnumJavaFile =\n        JavaFileObjects.forSourceLines(\n            \"com.example.enums.MyEnum\",\n            \"package com.example.enums;\",\n            \"\",\n            \"public enum MyEnum {\",\n            \"  ONE\",\n            \"}\");\n    JavaFileObject annotationFactoryJavaFile =\n        JavaFileObjects.forSourceLines(\n            \"com.example.factories.AnnotationFactory\",\n            \"package com.example.factories;\",\n            \"\",\n            \"import com.google.auto.value.AutoAnnotation;\",\n            \"import com.example.annotations.MyAnnotation;\",\n            \"import com.example.enums.MyEnum;\",\n            \"\",\n            \"import java.util.List;\",\n            \"import java.util.Set;\",\n            \"\",\n            \"public class AnnotationFactory {\",\n            \"  @AutoAnnotation\",\n            \"  public static MyAnnotation newMyAnnotation(\",\n            \"      List<Integer> value, Set<MyEnum> enums) {\",\n            \"    return new AutoAnnotation_AnnotationFactory_newMyAnnotation(value, enums);\",\n            \"  }\",\n            \"}\");\n    JavaFileObject expectedOutput =\n        JavaFileObjects.forSourceLines(\n            \"com.example.factories.AutoAnnotation_AnnotationFactory_newMyAnnotation\",\n            \"package com.example.factories;\",\n            \"\",\n            \"import com.example.annotations.MyAnnotation;\",\n            \"import com.example.enums.MyEnum;\",\n            \"import java.io.Serializable;\",\n            \"import java.util.Arrays;\",\n            \"import java.util.Collection;\",\n            \"import java.util.List;\",\n            \"import java.util.Set;\",\n            GeneratedImport.importGeneratedAnnotationType(),\n            \"\",\n            \"@Generated(\\\"\" + AutoAnnotationProcessor.class.getName() + \"\\\")\",\n            \"final class AutoAnnotation_AnnotationFactory_newMyAnnotation implements MyAnnotation,\"\n                + \" Serializable {\",\n            \"  private static final long serialVersionUID = -2102364343628921304L;\",\n            \"  private final int[] value;\",\n            \"  private final MyEnum[] enums;\",\n            \"\",\n            \"  AutoAnnotation_AnnotationFactory_newMyAnnotation(\",\n            \"      List<Integer> value,\",\n            \"      Set<MyEnum> enums) {\",\n            \"    if (value == null) {\",\n            \"      throw new NullPointerException(\\\"Null value\\\");\",\n            \"    }\",\n            \"    this.value = intArrayFromCollection(value);\",\n            \"    if (enums == null) {\",\n            \"      throw new NullPointerException(\\\"Null enums\\\");\",\n            \"    }\",\n            \"    this.enums = enums.toArray(new MyEnum[0]);\",\n            \"  }\",\n            \"\",\n            \"  @Override public Class<? extends MyAnnotation> annotationType() {\",\n            \"    return MyAnnotation.class;\",\n            \"  }\",\n            \"\",\n            \"  @Override public int[] value() {\",\n            \"    return value.clone();\",\n            \"  }\",\n            \"\",\n            \"  @Override public MyEnum[] enums() {\",\n            \"    return enums.clone();\",\n            \"  }\",\n            \"\",\n            \"  @Override public String toString() {\",\n            \"    StringBuilder sb = new StringBuilder(\\\"@com.example.annotations.MyAnnotation(\\\");\",\n            \"    sb.append(\\\"value=\\\");\",\n            \"    sb.append(Arrays.toString(value));\",\n            \"    sb.append(\\\", \\\");\",\n            \"    sb.append(\\\"enums=\\\");\",\n            \"    sb.append(Arrays.toString(enums));\",\n            \"    return sb.append(')').toString();\",\n            \"  }\",\n            \"\",\n            \"  @Override public boolean equals(Object o) {\",\n            \"    if (o == this) {\",\n            \"      return true;\",\n            \"    }\",\n            \"    if (o instanceof MyAnnotation) {\",\n            \"      MyAnnotation that = (MyAnnotation) o;\",\n            \"      return Arrays.equals(value,\",\n            \"          (that instanceof AutoAnnotation_AnnotationFactory_newMyAnnotation)\",\n            \"              ? ((AutoAnnotation_AnnotationFactory_newMyAnnotation) that).value\",\n            \"              : that.value())\",\n            \"          && Arrays.equals(enums,\",\n            \"          (that instanceof AutoAnnotation_AnnotationFactory_newMyAnnotation)\",\n            \"              ? ((AutoAnnotation_AnnotationFactory_newMyAnnotation) that).enums\",\n            \"              : that.enums());\",\n            \"    }\",\n            \"    return false;\",\n            \"  }\",\n            \"\",\n            \"  @Override public int hashCode() {\",\n            \"    return \",\n            \"        + (\" + 127 * \"value\".hashCode() + \" ^ Arrays.hashCode(value))\",\n            \"        + (\" + 127 * \"enums\".hashCode() + \" ^ Arrays.hashCode(enums));\",\n            \"  }\",\n            \"\",\n            \"  private static int[] intArrayFromCollection(Collection<Integer> c) {\",\n            \"    int[] a = new int[c.size()];\",\n            \"    int i = 0;\",\n            \"    for (int x : c) {\",\n            \"      a[i++] = x;\",\n            \"    }\",\n            \"    return a;\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoAnnotationProcessor())\n            .withOptions(\"-A\" + Nullables.NULLABLE_OPTION + \"=\")\n            .compile(annotationFactoryJavaFile, myEnumJavaFile, myAnnotationJavaFile);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\n            \"com.example.factories.AutoAnnotation_AnnotationFactory_newMyAnnotation\")\n        .hasSourceEquivalentTo(expectedOutput);\n  }\n\n  @Test\n  public void testMissingClass() {\n    // Test that referring to an undefined annotation does not trigger @AutoAnnotation processing.\n    // The class Erroneous references an undefined annotation @NotAutoAnnotation. If we didn't have\n    // any special treatment of undefined types then we could run into a compiler bug where\n    // AutoAnnotationProcessor would think that a method annotated with @NotAutoAnnotation was in\n    // fact annotated with @AutoAnnotation. As it is, we do get an error about @NotAutoAnnotation\n    // being undefined, and we do not get an error complaining that this supposed @AutoAnnotation\n    // method is not static. We do need to have @AutoAnnotation appear somewhere so that the\n    // processor will run.\n    JavaFileObject erroneousJavaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"com.example.annotations.Erroneous\",\n            \"package com.example.annotations;\",\n            \"\",\n            \"import com.google.auto.value.AutoAnnotation;\",\n            \"\",\n            \"public class Erroneous {\",\n            \"  @interface Empty {}\",\n            \"  @AutoAnnotation static Empty newEmpty() {}\",\n            \"  @NotAutoAnnotation Empty notNewEmpty() {}\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoAnnotationProcessor()).compile(erroneousJavaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"NotAutoAnnotation\")\n        .inFile(erroneousJavaFileObject)\n        .onLineContaining(\"@NotAutoAnnotation\");\n    assertThat(\n            compilation.errors().stream()\n                .map(diag -> diag.getMessage(null))\n                .filter(m -> m.contains(\"static\")))\n        .isEmpty();\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/AutoAnnotationErrorsTest.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.testing.compile.CompilationSubject.assertThat;\nimport static com.google.testing.compile.Compiler.javac;\n\nimport com.google.testing.compile.Compilation;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * Tests for compilation errors with the AutoAnnotation processor.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class AutoAnnotationErrorsTest {\n  private static final JavaFileObject TEST_ANNOTATION =\n      JavaFileObjects.forSourceLines(\n          \"com.example.TestAnnotation\",\n          \"package com.example;\",\n          \"\",\n          \"public @interface TestAnnotation {\",\n          \"  int value();\",\n          \"}\");\n\n  @Test\n  public void testCorrect() {\n    JavaFileObject testSource =\n        JavaFileObjects.forSourceLines(\n            \"com.foo.Test\",\n            \"package com.foo;\",\n            \"\",\n            \"import com.example.TestAnnotation;\",\n            \"import com.google.auto.value.AutoAnnotation;\",\n            \"\",\n            \"class Test {\",\n            \"  @AutoAnnotation static TestAnnotation newTestAnnotation(int value) {\",\n            \"    return new AutoAnnotation_Test_newTestAnnotation(value);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoAnnotationProcessor()).compile(TEST_ANNOTATION, testSource);\n    assertThat(compilation).succeededWithoutWarnings();\n  }\n\n  @Test\n  public void testDoesNotReturnAnnotation() {\n    JavaFileObject testSource =\n        JavaFileObjects.forSourceLines(\n            \"com.foo.Test\",\n            \"package com.foo;\",\n            \"\",\n            \"import com.google.auto.value.AutoAnnotation;\",\n            \"\",\n            \"class Test {\",\n            \"  @AutoAnnotation static String newString(int value) {\",\n            \"    return new AutoAnnotation_Test_newString(value);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoAnnotationProcessor()).compile(TEST_ANNOTATION, testSource);\n    assertThat(compilation)\n        .hadErrorContaining(\"must be an annotation type, not java.lang.String\")\n        .inFile(testSource)\n        .onLineContaining(\"static String newString(int value)\");\n  }\n\n  @Test\n  public void testOverload() {\n    JavaFileObject testSource =\n        JavaFileObjects.forSourceLines(\n            \"com.foo.Test\",\n            \"package com.foo;\",\n            \"\",\n            \"import com.example.TestAnnotation;\",\n            \"import com.google.auto.value.AutoAnnotation;\",\n            \"\",\n            \"class Test {\",\n            \"  @AutoAnnotation static TestAnnotation newTestAnnotation(int value) {\",\n            \"    return new AutoAnnotation_Test_newTestAnnotation(value);\",\n            \"  }\",\n            \"\",\n            \"  @AutoAnnotation static TestAnnotation newTestAnnotation(Integer value) {\",\n            \"    return new AutoAnnotation_Test_newTestAnnotation(value);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoAnnotationProcessor()).compile(TEST_ANNOTATION, testSource);\n    assertThat(compilation)\n        .hadErrorContaining(\"@AutoAnnotation methods cannot be overloaded\")\n        .inFile(testSource)\n        .onLineContaining(\"newTestAnnotation(Integer value)\");\n  }\n\n  // Overload detection used to detect all @AutoAnnotation methods that resulted in\n  // annotation class of the same SimpleName as being an overload.\n  // This verifies that implementations in different packages work correctly.\n  @Test\n  public void testSameNameDifferentPackagesDoesNotTriggerOverload() {\n\n    JavaFileObject fooTestSource =\n        JavaFileObjects.forSourceLines(\n            \"com.foo.Test\",\n            \"package com.foo;\",\n            \"\",\n            \"import com.example.TestAnnotation;\",\n            \"import com.google.auto.value.AutoAnnotation;\",\n            \"\",\n            \"class Test {\",\n            \"  @AutoAnnotation static TestAnnotation newTestAnnotation(int value) {\",\n            \"    return new AutoAnnotation_Test_newTestAnnotation(value);\",\n            \"  }\",\n            \"}\");\n    JavaFileObject barTestSource =\n        JavaFileObjects.forSourceLines(\n            \"com.bar.Test\",\n            \"package com.bar;\",\n            \"\",\n            \"import com.example.TestAnnotation;\",\n            \"import com.google.auto.value.AutoAnnotation;\",\n            \"\",\n            \"class Test {\",\n            \"  @AutoAnnotation static TestAnnotation newTestAnnotation(int value) {\",\n            \"    return new AutoAnnotation_Test_newTestAnnotation(value);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoAnnotationProcessor())\n            .compile(fooTestSource, barTestSource, TEST_ANNOTATION);\n    assertThat(compilation).succeededWithoutWarnings();\n  }\n\n  @Test\n  public void testWrongName() {\n    JavaFileObject testSource =\n        JavaFileObjects.forSourceLines(\n            \"com.foo.Test\",\n            \"package com.foo;\",\n            \"\",\n            \"import com.example.TestAnnotation;\",\n            \"import com.google.auto.value.AutoAnnotation;\",\n            \"\",\n            \"class Test {\",\n            \"  @AutoAnnotation static TestAnnotation newTestAnnotation(int fred) {\",\n            \"    return new AutoAnnotation_Test_newTestAnnotation(fred);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoAnnotationProcessor()).compile(TEST_ANNOTATION, testSource);\n    assertThat(compilation)\n        .hadErrorContaining(\"method parameter 'fred' must have the same name\")\n        .inFile(testSource)\n        .onLineContaining(\"newTestAnnotation(int fred)\");\n  }\n\n  @Test\n  public void testWrongType() {\n    JavaFileObject testSource =\n        JavaFileObjects.forSourceLines(\n            \"com.foo.Test\",\n            \"package com.foo;\",\n            \"\",\n            \"import com.example.TestAnnotation;\",\n            \"import com.google.auto.value.AutoAnnotation;\",\n            \"\",\n            \"class Test {\",\n            \"  @AutoAnnotation static TestAnnotation newTestAnnotation(String value) {\",\n            \"    return new AutoAnnotation_Test_newTestAnnotation(value);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoAnnotationProcessor()).compile(TEST_ANNOTATION, testSource);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"method parameter 'value' has type java.lang.String \"\n                + \"but com.example.TestAnnotation.value has type int\")\n        .inFile(testSource)\n        .onLineContaining(\"newTestAnnotation(String value)\");\n  }\n\n  @Test\n  public void testWrongTypeCollection() {\n    JavaFileObject testAnnotation =\n        JavaFileObjects.forSourceLines(\n            \"com.example.TestAnnotation\",\n            \"package com.example;\",\n            \"\",\n            \"public @interface TestAnnotation {\",\n            \"  int[] value();\",\n            \"}\");\n    String[] wrongTypes = {\n      \"java.util.List<java.lang.Long>\",\n      \"java.util.List<java.lang.String>\",\n      \"java.util.Set<java.lang.Long>\",\n      \"java.util.Map<java.lang.Integer,java.lang.Integer>\",\n      \"java.util.concurrent.Callable<java.lang.Integer>\",\n      \"java.util.List<int[]>\",\n    };\n    for (String wrongType : wrongTypes) {\n      JavaFileObject testSource =\n          JavaFileObjects.forSourceLines(\n              \"com.foo.Test\",\n              \"package com.foo;\",\n              \"\",\n              \"import com.example.TestAnnotation;\",\n              \"import com.google.auto.value.AutoAnnotation;\",\n              \"\",\n              \"class Test {\",\n              \"  @AutoAnnotation static TestAnnotation newTestAnnotation(\"\n                  + wrongType\n                  + \" value) {\",\n              \"    return new AutoAnnotation_Test_newTestAnnotation(value);\",\n              \"  }\",\n              \"}\");\n      Compilation compilation =\n          javac().withProcessors(new AutoAnnotationProcessor()).compile(testSource, testAnnotation);\n      assertThat(compilation)\n          .hadErrorContaining(\n              \"method parameter 'value' has type \"\n                  + wrongType\n                  + \" but com.example.TestAnnotation.value has type int[]\")\n          .inFile(testSource)\n          .onLineContaining(\"TestAnnotation newTestAnnotation(\");\n    }\n  }\n\n  @Test\n  public void testExtraParameters() {\n    JavaFileObject testSource =\n        JavaFileObjects.forSourceLines(\n            \"com.foo.Test\",\n            \"package com.foo;\",\n            \"\",\n            \"import com.example.TestAnnotation;\",\n            \"import com.google.auto.value.AutoAnnotation;\",\n            \"\",\n            \"class Test {\",\n            \"  @AutoAnnotation static TestAnnotation newTestAnnotation(int value, int other) {\",\n            \"    return new AutoAnnotation_Test_newTestAnnotation(value);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoAnnotationProcessor()).compile(TEST_ANNOTATION, testSource);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"method parameter 'other' must have the same name as a member of \"\n                + \"com.example.TestAnnotation\")\n        .inFile(testSource)\n        .onLineContaining(\"newTestAnnotation(int value, int other)\");\n  }\n\n  @Test\n  public void testMissingParameters() {\n    JavaFileObject testSource =\n        JavaFileObjects.forSourceLines(\n            \"com.foo.Test\",\n            \"package com.foo;\",\n            \"\",\n            \"import com.example.TestAnnotation;\",\n            \"import com.google.auto.value.AutoAnnotation;\",\n            \"\",\n            \"class Test {\",\n            \"  @AutoAnnotation static TestAnnotation newTestAnnotation() {\",\n            \"    return new AutoAnnotation_Test_newTestAnnotation();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoAnnotationProcessor()).compile(TEST_ANNOTATION, testSource);\n    assertThat(compilation)\n        .hadErrorContaining(\"method needs a parameter with name 'value' and type int\")\n        .inFile(testSource)\n        .onLineContaining(\"TestAnnotation newTestAnnotation()\");\n  }\n\n  @Test\n  public void testAnnotationValuedDefaultsNotSupportedYet() {\n    JavaFileObject annotationSource =\n        JavaFileObjects.forSourceLines(\n            \"com.example.TestAnnotation\",\n            \"package com.example;\",\n            \"\",\n            \"public @interface TestAnnotation {\",\n            \"  String value();\",\n            \"  Override optionalAnnotation() default @Override;\",\n            \"}\");\n    JavaFileObject testSource =\n        JavaFileObjects.forSourceLines(\n            \"com.foo.Test\",\n            \"package com.foo;\",\n            \"\",\n            \"import com.example.TestAnnotation;\",\n            \"import com.google.auto.value.AutoAnnotation;\",\n            \"\",\n            \"class Test {\",\n            \"  @AutoAnnotation static TestAnnotation newTestAnnotation(String value) {\",\n            \"    return new AutoAnnotation_Test_newTestAnnotation(value);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoAnnotationProcessor()).compile(annotationSource, testSource);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"@AutoAnnotation cannot yet supply a default value for annotation-valued member \"\n                + \"'optionalAnnotation'\")\n        .inFile(testSource)\n        .onLineContaining(\"TestAnnotation newTestAnnotation(String value)\");\n  }\n\n  @Test\n  public void testAnnotationMemberNameConflictWithGeneratedLocal() {\n    JavaFileObject annotationSource =\n        JavaFileObjects.forSourceLines(\n            \"com.example.TestAnnotation\",\n            \"package com.example;\",\n            \"\",\n            \"import java.lang.annotation.Annotation;\",\n            \"\",\n            \"public @interface TestAnnotation {\",\n            \"  Class<? extends Annotation>[] value();\",\n            \"  int value$();\",\n            \"}\");\n    JavaFileObject testSource =\n        JavaFileObjects.forSourceLines(\n            \"com.foo.Test\",\n            \"package com.foo;\",\n            \"\",\n            \"import java.lang.annotation.Annotation;\",\n            \"import java.util.Collection;\",\n            \"\",\n            \"import com.example.TestAnnotation;\",\n            \"import com.google.auto.value.AutoAnnotation;\",\n            \"\",\n            \"class Test {\",\n            \"  @AutoAnnotation static TestAnnotation newTestAnnotation(\",\n            \"     Collection<Class<? extends Annotation>> value, int value$) {\",\n            \"    return new AutoAnnotation_Test_newTestAnnotation(value, value$);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoAnnotationProcessor()).compile(annotationSource, testSource);\n    assertThat(compilation).hadErrorContaining(\"variable value$ is already defined in constructor\");\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/AutoBuilderCompilationTest.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.base.StandardSystemProperty.JAVA_SPECIFICATION_VERSION;\nimport static com.google.common.truth.TruthJUnit.assume;\nimport static com.google.testing.compile.CompilationSubject.assertThat;\nimport static com.google.testing.compile.Compiler.javac;\nimport static java.util.Arrays.stream;\nimport static java.util.stream.Collectors.joining;\n\nimport com.google.testing.compile.Compilation;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic final class AutoBuilderCompilationTest {\n  private static final JavaFileObject EXPECTED_SIMPLE_OUTPUT =\n      JavaFileObjects.forSourceLines(\n          \"foo.bar.AutoBuilder_Baz_Builder\",\n          \"package foo.bar;\",\n          \"\",\n          sorted(\n              GeneratedImport.importGeneratedAnnotationType(),\n              \"import org.jspecify.annotations.Nullable;\"),\n          \"\",\n          \"@Generated(\\\"\" + AutoBuilderProcessor.class.getName() + \"\\\")\",\n          \"class AutoBuilder_Baz_Builder implements Baz.Builder {\",\n          \"  private int anInt;\",\n          \"  private @Nullable String aString;\",\n          \"  private byte set$0;\",\n          \"\",\n          \"  AutoBuilder_Baz_Builder() {}\",\n          \"\",\n          \"  AutoBuilder_Baz_Builder(Baz source) {\",\n          \"    this.anInt = source.anInt();\",\n          \"    this.aString = source.aString();\",\n          \"    set$0 = (byte) 1;\",\n          \"  }\",\n          \"\",\n          \"  @Override public Baz.Builder setAnInt(int anInt) {\",\n          \"    this.anInt = anInt;\",\n          \"    set$0 |= (byte) 0x1;\",\n          \"    return this;\",\n          \"  }\",\n          \"\",\n          \"  @Override public Baz.Builder setAString(String aString) {\",\n          \"    if (aString == null) {\",\n          \"      throw new NullPointerException(\\\"Null aString\\\");\",\n          \"    }\",\n          \"    this.aString = aString;\",\n          \"    return this;\",\n          \"  }\",\n          \"\",\n          \"  @Override\",\n          \"  public Baz build() {\",\n          \"    if (set$0 != 0x1\",\n          \"          || this.aString == null) {\",\n          \"      StringBuilder missing = new StringBuilder();\",\n          \"      if ((set$0 & 0x1) == 0) {\",\n          \"        missing.append(\\\" anInt\\\");\",\n          \"      }\",\n          \"      if (this.aString == null) {\",\n          \"        missing.append(\\\" aString\\\");\",\n          \"      }\",\n          \"      throw new IllegalStateException(\\\"Missing required properties:\\\" + missing);\",\n          \"    }\",\n          \"    return new Baz(\",\n          \"        this.anInt,\",\n          \"        this.aString);\",\n          \"  }\",\n          \"}\");\n\n  @Test\n  public void simpleSuccess() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"public class Baz {\",\n            \"  private final int anInt;\",\n            \"  private final String aString;\",\n            \"\",\n            \"  public Baz(int anInt, String aString) {\",\n            \"    this.anInt = anInt;\",\n            \"    this.aString = aString;\",\n            \"  }\",\n            \"\",\n            \"  public int anInt() {\",\n            \"    return anInt;\",\n            \"  }\",\n            \"\",\n            \"  public String aString() {\",\n            \"    return aString;\",\n            \"  }\",\n            \"\",\n            \"  public static Builder builder() {\",\n            \"    return new AutoBuilder_Baz_Builder();\",\n            \"  }\",\n            \"\",\n            \"  @AutoBuilder\",\n            \"  public interface Builder {\",\n            \"    Builder setAnInt(int x);\",\n            \"    Builder setAString(String x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoBuilderProcessor())\n            .withOptions(\"-A\" + Nullables.NULLABLE_OPTION + \"=org.jspecify.annotations.Nullable\")\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoBuilder_Baz_Builder\")\n        .hasSourceEquivalentTo(EXPECTED_SIMPLE_OUTPUT);\n  }\n\n  @Test\n  public void simpleRecord() {\n    double version = Double.parseDouble(JAVA_SPECIFICATION_VERSION.value());\n    assume().that(version).isAtLeast(16.0);\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"public record Baz(int anInt, String aString) {\",\n            \"  public static Builder builder() {\",\n            \"    return new AutoBuilder_Baz_Builder();\",\n            \"  }\",\n            \"\",\n            \"  @AutoBuilder\",\n            \"  public interface Builder {\",\n            \"    Builder setAnInt(int x);\",\n            \"    Builder setAString(String x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoBuilderProcessor())\n            .withOptions(\"-A\" + Nullables.NULLABLE_OPTION + \"=org.jspecify.annotations.Nullable\")\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoBuilder_Baz_Builder\")\n        .hasSourceEquivalentTo(EXPECTED_SIMPLE_OUTPUT);\n  }\n\n  @Test\n  public void recordWithNullableTypeVariableComponents() {\n    double version = Double.parseDouble(JAVA_SPECIFICATION_VERSION.value());\n    assume().that(version).isAtLeast(16.0);\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"import org.jspecify.annotations.Nullable;\",\n            \"\",\n            \"public record Baz<T>(int anInt, @Nullable T aT) {\",\n            \"  public static Builder builder() {\",\n            \"    return new AutoBuilder_Baz_Builder();\",\n            \"  }\",\n            \"\",\n            \"  @AutoBuilder\",\n            \"  public interface Builder<T> {\",\n            \"    Builder setAnInt(int x);\",\n            \"    Builder setAT(@Nullable T x);\",\n            \"    Baz<T> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoBuilder_Baz_Builder\")\n        .contentsAsUtf8String()\n        .contains(\"public Baz.Builder<T> setAT(@Nullable T aT) {\");\n  }\n\n  @Test\n  public void recordWithNullableNestedComponentType() {\n    double version = Double.parseDouble(JAVA_SPECIFICATION_VERSION.value());\n    assume().that(version).isAtLeast(16.0);\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"import org.jspecify.annotations.Nullable;\",\n            \"\",\n            \"public record Baz(@Nullable Nested nested) {\",\n            \"  public static Builder builder() {\",\n            \"    return new AutoBuilder_Baz_Builder();\",\n            \"  }\",\n            \"\",\n            \"  @AutoBuilder\",\n            \"  public interface Builder {\",\n            \"    Builder setNested(Nested nested);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"\",\n            \"  public record Nested() {}\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoBuilderProcessor())\n            .withOptions(\"-A\" + Nullables.NULLABLE_OPTION + \"=org.jspecify.annotations.Nullable\")\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoBuilder_Baz_Builder\")\n        .contentsAsUtf8String()\n        .contains(\"private Baz.@Nullable Nested nested;\");\n  }\n\n  @Test\n  public void buildOtherPackage() {\n    JavaFileObject built =\n        JavaFileObjects.forSourceLines(\n            \"com.example.Built\",\n            \"package com.example;\",\n            \"\",\n            \"public class Built {\",\n            \"  private final int anInt;\",\n            \"  private final String aString;\",\n            \"\",\n            \"  public Built(int anInt, String aString) {\",\n            \"    this.anInt = anInt;\",\n            \"    this.aString = aString;\",\n            \"  }\",\n            \"}\");\n    JavaFileObject builder =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Builder\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.example.Built;\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"@AutoBuilder(ofClass = Built.class)\",\n            \"public interface Builder {\",\n            \"  public static Builder builder() {\",\n            \"    return new AutoBuilder_Builder();\",\n            \"  }\",\n            \"\",\n            \"  Builder setAnInt(int x);\",\n            \"  Builder setAString(String x);\",\n            \"  Built build();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(built, builder);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation).generatedSourceFile(\"foo.bar.AutoBuilder_Builder\");\n  }\n\n  @Test\n  public void autoBuilderOnEnum() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"@AutoBuilder\",\n            \"public enum Baz {\",\n            \"  ZIG, ZAG, DUSTIN,\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoBuilderWrongType] @AutoBuilder only applies to classes and interfaces\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"enum Baz\");\n  }\n\n  @Test\n  public void autoBuilderPrivate() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"public class Baz {\",\n            \"  @AutoBuilder\",\n            \"  private interface Builder {\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\"[AutoBuilderPrivate] @AutoBuilder class must not be private\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"interface Builder\");\n  }\n\n  @Test\n  public void autoBuilderClassMustHaveNoArgConstructor() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"public class Baz {\",\n            \"  @AutoBuilder\",\n            \"  abstract static class Builder {\",\n            \"    Builder(int bogus) {}\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoBuilderProcessor())\n            .withOptions(\"-Acom.google.auto.value.AutoBuilderIsUnstable\")\n            .compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoBuilderConstructor] @AutoBuilder class must have a non-private no-arg\"\n                + \" constructor\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"class Builder\");\n  }\n\n  @Test\n  public void autoBuilderClassMustHaveVisibleNoArgConstructor() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"public class Baz {\",\n            \"  @AutoBuilder\",\n            \"  abstract static class Builder {\",\n            \"    private Builder() {}\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoBuilderProcessor())\n            .withOptions(\"-Acom.google.auto.value.AutoBuilderIsUnstable\")\n            .compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoBuilderConstructor] @AutoBuilder class must have a non-private no-arg\"\n                + \" constructor\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"class Builder\");\n  }\n\n  @Test\n  public void autoBuilderMissingBuildMethod() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"public class Baz {\",\n            \"  private final int anInt;\",\n            \"  private final String aString;\",\n            \"\",\n            \"  public Baz(int anInt, String aString) {\",\n            \"    this.anInt = anInt;\",\n            \"    this.aString = aString;\",\n            \"  }\",\n            \"\",\n            \"  public int anInt() {\",\n            \"    return anInt;\",\n            \"  }\",\n            \"\",\n            \"  public String aString() {\",\n            \"    return aString;\",\n            \"  }\",\n            \"\",\n            \"  public static Builder builder() {\",\n            \"    return new AutoBuilder_Baz_Builder();\",\n            \"  }\",\n            \"\",\n            \"  @AutoBuilder\",\n            \"  public interface Builder {\",\n            \"    Builder setAnInt(int x);\",\n            \"    Builder setAString(String x);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoValueBuilderBuild] Builder must have a single no-argument method, typically\"\n                + \" called build(), that returns foo.bar.Baz\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"interface Builder\");\n  }\n\n  @Test\n  public void autoBuilderNestedInPrivate() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"public class Baz {\",\n            \"  private static class Private {\",\n            \"    @AutoBuilder\",\n            \"    public interface Builder {\",\n            \"      Baz build();\",\n            \"    }\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoBuilderInPrivate] @AutoBuilder class must not be nested in a private class\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"interface Builder\");\n  }\n\n  @Test\n  public void autoBuilderInner() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"public class Baz {\",\n            \"  @AutoBuilder\",\n            \"  abstract class Builder {\",\n            \"    abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\"[AutoBuilderInner] Nested @AutoBuilder class must be static\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"class Builder\");\n  }\n\n  @Test\n  public void innerConstructor() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"public class Baz {\",\n            \"  class Inner {}\",\n            \"\",\n            \"  @AutoBuilder(ofClass = Inner.class)\",\n            \"  interface Builder {\",\n            \"    abstract Inner build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\"[AutoBuilderInner] Nested @AutoBuilder ofClass class must be static\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"interface Builder\");\n  }\n\n  @Test\n  public void noVisibleConstructor() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"public class Baz {\",\n            \"  @AutoBuilder(ofClass = System.class)\",\n            \"  interface Builder {\",\n            \"    abstract System build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\"[AutoBuilderNoVisible] No visible constructor for java.lang.System\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"interface Builder\");\n  }\n\n  @Test\n  public void noVisibleMethod() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"public class Baz {\",\n            \"  private static Baz of() {\",\n            \"    return new Baz();\",\n            \"  }\",\n            \"\",\n            \"  @AutoBuilder(callMethod = \\\"of\\\")\",\n            \"  interface Builder {\",\n            \"    abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoBuilderNoVisible] No visible static method named \\\"of\\\" for foo.bar.Baz\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"interface Builder\");\n  }\n\n  @Test\n  public void methodNotStatic() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"public class Baz {\",\n            \"  Baz of() {\",\n            \"    return this;\",\n            \"  }\",\n            \"\",\n            \"  @AutoBuilder(callMethod = \\\"of\\\")\",\n            \"  interface Builder {\",\n            \"    abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoBuilderNoVisible] No visible static method named \\\"of\\\" for foo.bar.Baz\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"interface Builder\");\n  }\n\n  @Test\n  public void noMatchingConstructor() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"public class Baz {\",\n            \"  public Baz(int notMe) {}\",\n            \"\",\n            \"  public Baz(String notMeEither) {}\",\n            \"\",\n            \"  @AutoBuilder\",\n            \"  interface Builder {\",\n            \"    Builder setBuh(String x);\",\n            \"    abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoBuilderNoMatch] Property names do not correspond to the parameter names of any\"\n                + \" constructor:\\n\"\n                + \"    Baz(int notMe)\\n\"\n                + \"    Baz(java.lang.String notMeEither)\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"interface Builder\");\n  }\n\n  @Test\n  public void twoMatchingConstructors() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"public class Baz {\",\n            \"  public Baz() {}\",\n            \"\",\n            \"  public Baz(int buh) {}\",\n            \"\",\n            \"  public Baz(String buh) {}\",\n            \"\",\n            \"  @AutoBuilder\",\n            \"  interface Builder {\",\n            \"    Builder setBuh(String x);\",\n            \"    abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoBuilderAmbiguous] Property names correspond to more than one constructor:\\n\"\n                + \"    Baz(int buh)\\n\"\n                + \"    Baz(java.lang.String buh)\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"interface Builder\");\n  }\n\n  @Test\n  public void constructInterface() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"public interface Baz {\",\n            \"  @AutoBuilder\",\n            \"  interface Builder {\",\n            \"    abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoBuilderEnclosing] @AutoBuilder must specify ofClass=Something.class or it must\"\n                + \" be nested inside the class to be built; actually nested inside interface\"\n                + \" foo.bar.Baz\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"interface Builder\");\n  }\n\n  @Test\n  public void inconsistentSetPrefix() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"class Baz {\",\n            \"  Baz(int one, int two) {}\",\n            \"\",\n            \"  @AutoBuilder\",\n            \"  interface Builder {\",\n            \"    abstract Builder one(int x);\",\n            \"    abstract Builder setTwo(int x);\",\n            \"    abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoBuilderSetNotSet] If any setter methods use the setFoo convention then all must\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"Builder one(int x)\");\n  }\n\n  @Test\n  public void missingSetter() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"class Baz {\",\n            \"  Baz(int one, int two) {}\",\n            \"\",\n            \"  @AutoBuilder\",\n            \"  interface Builder {\",\n            \"    abstract Builder one(int x);\",\n            \"    abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoBuilderBuilderMissingMethod] Expected a method with this signature:\"\n                + \" foo.bar.Baz.Builder two(int), or a twoBuilder() method\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"interface Builder\");\n  }\n\n  @Test\n  public void tooManyArgs() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"class Baz {\",\n            \"  Baz(int one, int two) {}\",\n            \"\",\n            \"  @AutoBuilder\",\n            \"  interface Builder {\",\n            \"    abstract Builder one(int x);\",\n            \"    abstract Builder two(int x);\",\n            \"    abstract Builder many(int x, int y);\",\n            \"    abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\"[AutoBuilderBuilderArgs] Builder methods must have 0 or 1 parameters\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"many(int x, int y)\");\n  }\n\n  @Test\n  public void alienNoArgMethod() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"class Baz {\",\n            \"  Baz(int one, int two) {}\",\n            \"\",\n            \"  @AutoBuilder\",\n            \"  interface Builder {\",\n            \"    abstract Builder one(int x);\",\n            \"    abstract Builder two(int x);\",\n            \"    abstract String alien();\",\n            \"    abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoBuilderBuilderNoArg] Method without arguments should be a build method returning\"\n                + \" foo.bar.Baz, or a getter method with the same name and type as a parameter of\"\n                + \" Baz(int one, int two), or fooBuilder() where foo is a parameter of Baz(int\"\n                + \" one, int two)\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"String alien()\");\n  }\n\n  @Test\n  public void alienOneArgMethod() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"class Baz {\",\n            \"  Baz(int one, int two) {}\",\n            \"\",\n            \"  @AutoBuilder\",\n            \"  interface Builder {\",\n            \"    abstract Builder one(int x);\",\n            \"    abstract Builder two(int x);\",\n            \"    abstract Builder three(int x);\",\n            \"    abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoBuilderBuilderWhatProp] Method three does not correspond to \"\n                + \"a parameter of Baz(int one, int two)\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"three(int x)\");\n  }\n\n  @Test\n  public void setterReturnType() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"class Baz {\",\n            \"  Baz(int one, int two) {}\",\n            \"\",\n            \"  @AutoBuilder\",\n            \"  interface Builder {\",\n            \"    abstract Builder one(int x);\",\n            \"    abstract void two(int x);\",\n            \"    abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoBuilderBuilderRet] Setter methods must return foo.bar.Baz.Builder or a supertype\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"two(int x)\");\n  }\n\n  @Test\n  public void nullableSetterForNonNullableParameter() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"import com.example.annotations.Nullable;\",\n            \"\",\n            \"class Baz {\",\n            \"  Baz(String thing) {}\",\n            \"\",\n            \"  @AutoBuilder\",\n            \"  interface Builder {\",\n            \"    abstract Builder thing(@Nullable String x);\",\n            \"    abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    JavaFileObject nullableFileObject =\n        JavaFileObjects.forSourceLines(\n            \"com.example.annotations.Nullable\",\n            \"package com.example.annotations;\",\n            \"\",\n            \"import java.lang.annotation.ElementType;\",\n            \"import java.lang.annotation.Target;\",\n            \"\",\n            \"@Target(ElementType.TYPE_USE)\",\n            \"public @interface Nullable {}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoBuilderProcessor())\n            .compile(javaFileObject, nullableFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoBuilderNullNotNull] Parameter of setter method is @Nullable but parameter\"\n                + \" \\\"thing\\\" of Baz(java.lang.String thing) is not\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"thing(@Nullable String x)\");\n  }\n\n  @Test\n  public void nullablePrimitiveParameter() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"import com.example.annotations.Nullable;\",\n            \"\",\n            \"class Baz {\",\n            \"  Baz(@Nullable int thing) {}\",\n            \"\",\n            \"  @AutoBuilder\",\n            \"  interface Builder {\",\n            \"    abstract Builder thing(int x);\",\n            \"    abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    JavaFileObject nullableFileObject =\n        JavaFileObjects.forSourceLines(\n            \"com.example.annotations.Nullable\",\n            \"package com.example.annotations;\",\n            \"\",\n            \"import java.lang.annotation.ElementType;\",\n            \"import java.lang.annotation.Target;\",\n            \"\",\n            \"@Target(ElementType.TYPE_USE)\",\n            \"public @interface Nullable {}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoBuilderProcessor())\n            .compile(javaFileObject, nullableFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\"[AutoBuilderNullPrimitive] Primitive types cannot be @Nullable\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"Baz(@Nullable int thing)\");\n  }\n\n  @Test\n  public void setterWrongType() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"class Baz {\",\n            \"  Baz(int up, int down) {}\",\n            \"\",\n            \"  @AutoBuilder\",\n            \"  interface Builder {\",\n            \"    abstract Builder up(int x);\",\n            \"    abstract Builder down(String x);\",\n            \"    abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoBuilderGetVsSet] Parameter type java.lang.String of setter method should be int\"\n                + \" to match parameter \\\"down\\\" of Baz(int up, int down)\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"down(String x)\");\n  }\n\n  @Test\n  public void setterWrongTypeEvenWithConversion() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"import java.util.Optional;\",\n            \"\",\n            \"class Baz {\",\n            \"  Baz(Optional<String> maybe) {}\",\n            \"\",\n            \"  @AutoBuilder\",\n            \"  interface Builder {\",\n            \"    abstract Builder maybe(int x);\",\n            \"    abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoBuilderGetVsSetOrConvert] Parameter type int of setter method should be\"\n                + \" java.util.Optional<java.lang.String> to match parameter \\\"maybe\\\" of\"\n                + \" Baz(java.util.Optional<java.lang.String> maybe), or it should be a type that\"\n                + \" can be passed to Optional.of to produce java.util.Optional<java.lang.String>\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"maybe(int x)\");\n  }\n\n  @Test\n  public void typeParamMismatch() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"import java.util.Optional;\",\n            \"\",\n            \"class Baz<T> {\",\n            \"  Baz(T param) {}\",\n            \"\",\n            \"  @AutoBuilder\",\n            \"  interface Builder<E> {\",\n            \"    abstract Builder<E> param(E param);\",\n            \"    abstract Baz<E> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoBuilderTypeParams] Builder type parameters <E> must match type parameters <T> of\"\n                + \" Baz(T param)\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"interface Builder<E>\");\n  }\n\n  @Test\n  public void annotationWithCallMethod() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoBuilder;\",\n            \"\",\n            \"class Baz {\",\n            \"  @interface MyAnnot {\",\n            \"    boolean broken();\",\n            \"  }\",\n            \"\",\n            \"  @AutoBuilder(callMethod = \\\"annotationType\\\", ofClass = MyAnnot.class)\",\n            \"  interface Builder {\",\n            \"    abstract Builder broken(boolean x);\",\n            \"    abstract MyAnnot build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"[AutoBuilderAnnotationMethod] @AutoBuilder for an annotation must have an empty\"\n                + \" callMethod, not \\\"annotationType\\\"\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"interface Builder\");\n  }\n\n  private static String sorted(String... imports) {\n    return stream(imports).sorted().collect(joining(\"\\n\"));\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/AutoOneOfCompilationTest.java",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.testing.compile.CompilationSubject.assertThat;\nimport static com.google.testing.compile.Compiler.javac;\n\nimport com.google.common.truth.Expect;\nimport com.google.testing.compile.Compilation;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class AutoOneOfCompilationTest {\n  @Rule public final Expect expect = Expect.create();\n\n  @Test\n  public void success() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.TaskResult\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoOneOf;\",\n            \"import java.io.Serializable;\",\n            \"\",\n            \"@AutoOneOf(TaskResult.Kind.class)\",\n            \"public abstract class TaskResult<V, T extends Throwable> implements Serializable {\",\n            \"  private static final long serialVersionUID = 1234L;\",\n            \"\",\n            \"  public enum Kind {VALUE, EXCEPTION, EMPTY}\",\n            \"  public abstract Kind getKind();\",\n            \"\",\n            \"  public abstract V value();\",\n            \"  public abstract Throwable exception();\",\n            \"  public abstract void empty();\",\n            \"\",\n            \"  public static <V> TaskResult<V, ?> value(V value) {\",\n            \"    return AutoOneOf_TaskResult.value(value);\",\n            \"  }\",\n            \"\",\n            \"  public static <T extends Throwable> TaskResult<?, T> exception(T exception) {\",\n            \"    return AutoOneOf_TaskResult.exception(exception);\",\n            \"  }\",\n            \"}\");\n    JavaFileObject expectedOutput =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.AutoOneOf_TaskResult\",\n            \"package foo.bar;\",\n            \"\",\n            \"import java.util.Objects;\",\n            GeneratedImport.importGeneratedAnnotationType(),\n            \"\",\n            \"@Generated(\\\"com.google.auto.value.processor.AutoOneOfProcessor\\\")\",\n            \"final class AutoOneOf_TaskResult {\",\n            \"  private AutoOneOf_TaskResult() {} // There are no instances of this type.\",\n            \"\",\n            \"  static <V, T extends Throwable> TaskResult<V, T> value(V value) {\",\n            \"    Objects.requireNonNull(value);\",\n            \"    return new Impl_value<V, T>(value);\",\n            \"  }\",\n            \"\",\n            \"  static <V, T extends Throwable> TaskResult<V, T> exception(Throwable exception) {\",\n            \"    Objects.requireNonNull(exception);\",\n            \"    return new Impl_exception<V, T>(exception);\",\n            \"  }\",\n            \"\",\n            \"  @SuppressWarnings(\\\"unchecked\\\") // type parameters are unused in void instances\",\n            \"  static <V, T extends Throwable> TaskResult<V, T> empty() {\",\n            \"    return (TaskResult<V, T>) Impl_empty.INSTANCE;\",\n            \"  }\",\n            \"\",\n            \"  // Parent class that each implementation will inherit from.\",\n            \"  private abstract static class Parent_<V, T extends Throwable> \"\n                + \"extends TaskResult<V, T> {\",\n            \"    private static final long serialVersionUID = 1234L;\",\n            \"\",\n            \"    @Override\",\n            \"    public V value() {\",\n            \"      throw new UnsupportedOperationException(getKind().toString());\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public Throwable exception() {\",\n            \"      throw new UnsupportedOperationException(getKind().toString());\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public void empty() {\",\n            \"      throw new UnsupportedOperationException(getKind().toString());\",\n            \"    }\",\n            \"  }\",\n            \"\",\n            \"  // Implementation when the contained property is \\\"value\\\".\",\n            \"  private static final class Impl_value<V, T extends Throwable> \"\n                + \"extends Parent_<V, T> {\",\n            \"    private static final long serialVersionUID = 1234L;\",\n            \"\",\n            \"    private final V value;\",\n            \"\",\n            \"    Impl_value(V value) {\",\n            \"      this.value = value;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public V value() {\",\n            \"      return value;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public String toString() {\",\n            \"      return \\\"TaskResult{value=\\\" + this.value + \\\"}\\\";\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public boolean equals(Object x) {\",\n            \"      if (x instanceof TaskResult) {\",\n            \"        TaskResult<?, ?> that = (TaskResult<?, ?>) x;\",\n            \"        return this.getKind() == that.getKind()\",\n            \"            && this.value.equals(that.value());\",\n            \"      } else {\",\n            \"        return false;\",\n            \"      }\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public int hashCode() {\",\n            \"      return value.hashCode();\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public TaskResult.Kind getKind() {\",\n            \"      return TaskResult.Kind.VALUE;\",\n            \"    }\",\n            \"  }\",\n            \"\",\n            \"  // Implementation when the contained property is \\\"exception\\\".\",\n            \"  private static final class Impl_exception<V, T extends Throwable> \"\n                + \"extends Parent_<V, T> {\",\n            \"    private static final long serialVersionUID = 1234L;\",\n            \"\",\n            \"    private final Throwable exception;\",\n            \"\",\n            \"    Impl_exception(Throwable exception) {\",\n            \"      this.exception = exception;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public Throwable exception() {\",\n            \"      return exception;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public String toString() {\",\n            \"      return \\\"TaskResult{exception=\\\" + this.exception + \\\"}\\\";\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public boolean equals(Object x) {\",\n            \"      if (x instanceof TaskResult) {\",\n            \"        TaskResult<?, ?> that = (TaskResult<?, ?>) x;\",\n            \"        return this.getKind() == that.getKind()\",\n            \"            && this.exception.equals(that.exception());\",\n            \"      } else {\",\n            \"        return false;\",\n            \"      }\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public int hashCode() {\",\n            \"      return exception.hashCode();\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public TaskResult.Kind getKind() {\",\n            \"      return TaskResult.Kind.EXCEPTION;\",\n            \"    }\",\n            \"  }\",\n            \"\",\n            \"  // Implementation when the contained property is \\\"empty\\\".\",\n            \"  private static final class Impl_empty<V, T extends Throwable> \"\n                + \"extends Parent_<V, T> {\",\n            \"    private static final long serialVersionUID = 1234L;\",\n            \"\",\n            \"    static final Impl_empty<?, ?> INSTANCE = new Impl_empty<>();\",\n            \"\",\n            \"    private Impl_empty() {}\",\n            \"\",\n            \"    @Override\",\n            \"    public void empty() {}\",\n            \"\",\n            \"    private Object readResolve() {\",\n            \"      return INSTANCE;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public String toString() {\",\n            \"      return \\\"TaskResult{empty}\\\";\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public boolean equals(Object x) {\",\n            \"      return x == this;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public int hashCode() {\",\n            \"      return System.identityHashCode(this);\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public TaskResult.Kind getKind() {\",\n            \"      return TaskResult.Kind.EMPTY;\",\n            \"    }\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoOneOfProcessor())\n            .withOptions(\n                \"-Xlint:-processing\", \"-implicit:none\", \"-A\" + Nullables.NULLABLE_OPTION + \"=\")\n            .compile(javaFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoOneOf_TaskResult\")\n        .hasSourceEquivalentTo(expectedOutput);\n  }\n\n  @Test\n  public void voidInstanceWithoutGenericTypeParameters() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Nothing\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoOneOf;\",\n            \"import java.io.Serializable;\",\n            \"\",\n            \"@AutoOneOf(Nothing.Kind.class)\",\n            \"abstract class Nothing {\",\n            \"\",\n            \"  enum Kind {NOTHING}\",\n            \"\",\n            \"  abstract Kind kind();\",\n            \"\",\n            \"  abstract void nothing();\",\n            \"}\");\n    JavaFileObject expectedOutput =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Nothing\",\n            \"package foo.bar;\",\n            \"\",\n            GeneratedImport.importGeneratedAnnotationType(),\n            \"\",\n            \"@Generated(\\\"com.google.auto.value.processor.AutoOneOfProcessor\\\")\",\n            \"final class AutoOneOf_Nothing {\",\n            \"  private AutoOneOf_Nothing() {} // There are no instances of this type.\",\n            \"\",\n            \"  static Nothing nothing() {\",\n            \"    return Impl_nothing.INSTANCE;\",\n            \"  }\",\n            \"\",\n            \"  // Parent class that each implementation will inherit from.\",\n            \"  private abstract static class Parent_ extends Nothing {\",\n            \"    @Override\",\n            \"    void nothing() {\",\n            \"      throw new UnsupportedOperationException(kind().toString());\",\n            \"    }\",\n            \"  }\",\n            \"\",\n            \"  // Implementation when the contained property is \\\"nothing\\\".\",\n            \"  private static final class Impl_nothing extends Parent_ {\",\n            \"    // There is only one instance of this class.\",\n            \"    static final Impl_nothing INSTANCE = new Impl_nothing();\",\n            \"\",\n            \"    private Impl_nothing() {}\",\n            \"\",\n            \"    @Override\",\n            \"    public void nothing() {}\",\n            \"\",\n            \"    @Override\",\n            \"    public String toString() {\",\n            \"      return \\\"Nothing{nothing}\\\";\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public boolean equals(Object x) {\",\n            \"      return x == this;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public int hashCode() {\",\n            \"      return System.identityHashCode(this);\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public Nothing.Kind kind() {\",\n            \"      return Nothing.Kind.NOTHING;\",\n            \"    }\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoOneOfProcessor())\n            .withOptions(\n                \"-Xlint:-processing\", \"-implicit:none\", \"-A\" + Nullables.NULLABLE_OPTION + \"=\")\n            .compile(javaFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoOneOf_Nothing\")\n        .hasSourceEquivalentTo(expectedOutput);\n  }\n\n  @Test\n  public void noKindGetter() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Pet\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoOneOf;\",\n            \"\",\n            \"@AutoOneOf(Pet.Kind.class)\",\n            \"public abstract class Pet {\",\n            \"  public enum Kind {DOG, CAT}\",\n            \"  public abstract String dog();\",\n            \"  public abstract String cat();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoOneOfProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"foo.bar.Pet must have a no-arg abstract method returning foo.bar.Pet.Kind\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"class Pet\");\n  }\n\n  @Test\n  public void kindGetterHasParam() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Pet\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoOneOf;\",\n            \"\",\n            \"@AutoOneOf(Pet.Kind.class)\",\n            \"public abstract class Pet {\",\n            \"  public enum Kind {DOG, CAT}\",\n            \"  public abstract Kind getKind(String wut);\",\n            \"  public abstract String dog();\",\n            \"  public abstract String cat();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoOneOfProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"foo.bar.Pet must have a no-arg abstract method returning foo.bar.Pet.Kind\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"class Pet\");\n  }\n\n  @Test\n  public void twoKindGetters() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Pet\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoOneOf;\",\n            \"\",\n            \"@AutoOneOf(Pet.Kind.class)\",\n            \"public abstract class Pet {\",\n            \"  public enum Kind {DOG, CAT}\",\n            \"  public abstract Kind getKind();\",\n            \"  public abstract Kind alsoGetKind();\",\n            \"  public abstract String dog();\",\n            \"  public abstract String cat();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoOneOfProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"More than one abstract method returns foo.bar.Pet.Kind\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"getKind\");\n    assertThat(compilation)\n        .hadErrorContaining(\"More than one abstract method returns foo.bar.Pet.Kind\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"alsoGetKind\");\n  }\n\n  @Test\n  public void enumMissingCase() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Pet\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoOneOf;\",\n            \"\",\n            \"@AutoOneOf(Pet.Kind.class)\",\n            \"public abstract class Pet {\",\n            \"  public enum Kind {DOG}\",\n            \"  public abstract Kind getKind();\",\n            \"  public abstract String dog();\",\n            \"  public abstract String cat();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoOneOfProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"Enum has no constant with name corresponding to property 'cat'\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"enum Kind\");\n  }\n\n  @Test\n  public void enumExtraCase() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Pet\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoOneOf;\",\n            \"\",\n            \"@AutoOneOf(Pet.Kind.class)\",\n            \"public abstract class Pet {\",\n            \"  public enum Kind {\",\n            \"    DOG,\",\n            \"    CAT,\",\n            \"    GERBIL,\",\n            \"  }\",\n            \"  public abstract Kind getKind();\",\n            \"  public abstract String dog();\",\n            \"  public abstract String cat();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoOneOfProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Name of enum constant 'GERBIL' does not correspond to any property name\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"GERBIL\");\n  }\n\n  @Test\n  public void mustBeClass() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Pet\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoOneOf;\",\n            \"\",\n            \"@AutoOneOf(Pet.Kind.class)\",\n            \"public interface Pet {\",\n            \"  public enum Kind {\",\n            \"    DOG,\",\n            \"    CAT,\",\n            \"  }\",\n            \"  Kind getKind();\",\n            \"  String dog();\",\n            \"  String cat();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoOneOfProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"@AutoOneOf only applies to classes\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"interface Pet\");\n  }\n\n  @Test\n  public void cantBeNullable() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Pet\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoOneOf;\",\n            \"\",\n            \"@AutoOneOf(Pet.Kind.class)\",\n            \"public abstract class Pet {\",\n            \"  @interface Nullable {}\",\n            \"\",\n            \"  public enum Kind {\",\n            \"    DOG,\",\n            \"    CAT,\",\n            \"  }\",\n            \"  public abstract Kind getKind();\",\n            \"  public abstract @Nullable String dog();\",\n            \"  public abstract String cat();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoOneOfProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"@AutoOneOf properties cannot be @Nullable\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"@Nullable String dog()\");\n  }\n\n  @Test\n  public void mustHaveNoArgConstructor() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Pet\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoOneOf;\",\n            \"\",\n            \"@AutoOneOf(Pet.Kind.class)\",\n            \"public abstract class Pet {\",\n            \"  Pet(boolean cuddly) {}\",\n            \"\",\n            \"  public enum Kind {\",\n            \"    DOG,\",\n            \"    CAT,\",\n            \"  }\",\n            \"  public abstract Kind getKind();\",\n            \"  public abstract String dog();\",\n            \"  public abstract String cat();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoOneOfProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"@AutoOneOf class must have a non-private no-arg constructor\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"class Pet\");\n  }\n\n  @Test\n  public void mustHaveVisibleNoArgConstructor() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Pet\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoOneOf;\",\n            \"\",\n            \"@AutoOneOf(Pet.Kind.class)\",\n            \"public abstract class Pet {\",\n            \"  private Pet() {}\",\n            \"\",\n            \"  public enum Kind {\",\n            \"    DOG,\",\n            \"    CAT,\",\n            \"  }\",\n            \"  public abstract Kind getKind();\",\n            \"  public abstract String dog();\",\n            \"  public abstract String cat();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoOneOfProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"@AutoOneOf class must have a non-private no-arg constructor\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"class Pet\");\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/AutoValueCompilationTest.java",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.base.StandardSystemProperty.JAVA_SPECIFICATION_VERSION;\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.common.truth.TruthJUnit.assume;\nimport static com.google.testing.compile.CompilationSubject.assertThat;\nimport static com.google.testing.compile.CompilationSubject.compilations;\nimport static com.google.testing.compile.Compiler.javac;\nimport static java.util.Arrays.stream;\nimport static java.util.stream.Collectors.joining;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.truth.Expect;\nimport com.google.testing.compile.Compilation;\nimport com.google.testing.compile.JavaFileObjects;\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.io.UncheckedIOException;\nimport java.io.Writer;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.util.Set;\nimport javax.annotation.processing.AbstractProcessor;\nimport javax.annotation.processing.RoundEnvironment;\nimport javax.annotation.processing.SupportedAnnotationTypes;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.TypeParameterElement;\nimport javax.lang.model.util.ElementFilter;\nimport javax.tools.JavaFileObject;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class AutoValueCompilationTest {\n  @Rule public final Expect expect = Expect.create();\n\n  // Sadly we can't rely on JDK 8 to handle type annotations correctly.\n  // Some versions do, some don't. So skip the test unless we are on at least JDK 9.\n  private boolean typeAnnotationsWork =\n      Double.parseDouble(JAVA_SPECIFICATION_VERSION.value()) >= 9.0;\n\n  @Test\n  public void simpleSuccess() {\n    // Positive test case that ensures we generate the expected code for at least one case.\n    // Most AutoValue code-generation tests are functional, meaning that we check that the generated\n    // code does the right thing rather than checking what it looks like, but this test checks that\n    // we are not generating correct but weird code.\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  public abstract long buh();\",\n            \"\",\n            \"  public static Baz create(long buh) {\",\n            \"    return new AutoValue_Baz(buh);\",\n            \"  }\",\n            \"}\");\n    JavaFileObject expectedOutput =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.AutoValue_Baz\",\n            \"package foo.bar;\",\n            \"\",\n            GeneratedImport.importGeneratedAnnotationType(),\n            \"\",\n            \"@Generated(\\\"\" + AutoValueProcessor.class.getName() + \"\\\")\",\n            \"final class AutoValue_Baz extends Baz {\",\n            \"  private final long buh;\",\n            \"\",\n            \"  AutoValue_Baz(long buh) {\",\n            \"    this.buh = buh;\",\n            \"  }\",\n            \"\",\n            \"  @Override public long buh() {\",\n            \"    return buh;\",\n            \"  }\",\n            \"\",\n            \"  @Override public String toString() {\",\n            \"    return \\\"Baz{\\\"\",\n            \"        + \\\"buh=\\\" + buh\",\n            \"        + \\\"}\\\";\",\n            \"  }\",\n            \"\",\n            \"  @Override public boolean equals(Object o) {\",\n            \"    if (o == this) {\",\n            \"      return true;\",\n            \"    }\",\n            \"    if (o instanceof Baz) {\",\n            \"      Baz that = (Baz) o;\",\n            \"      return this.buh == that.buh();\",\n            \"    }\",\n            \"    return false;\",\n            \"  }\",\n            \"\",\n            \"  @Override public int hashCode() {\",\n            \"    int h$ = 1;\",\n            \"    h$ *= 1000003;\",\n            \"    h$ ^= (int) ((buh >>> 32) ^ buh);\",\n            \"    return h$;\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor())\n            .withOptions(\"-A\" + Nullables.NULLABLE_OPTION + \"=\")\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Baz\")\n        .hasSourceEquivalentTo(expectedOutput);\n  }\n\n  @Test\n  public void importTwoWays() {\n    // Test that referring to the same class in two different ways does not confuse the import logic\n    // into thinking it is two different classes and that therefore it can't import. The code here\n    // is nonsensical but successfully reproduces a real problem, which is that a TypeMirror that is\n    // extracted using Elements.getTypeElement(name).asType() does not compare equal to one that is\n    // extracted from ExecutableElement.getReturnType(), even though Types.isSameType considers them\n    // equal. So unless we are careful, the java.util.Arrays that we import explicitly to use its\n    // methods will appear different from the java.util.Arrays that is the return type of the\n    // arrays() method here.\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"import java.util.Arrays;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  @SuppressWarnings(\\\"mutable\\\")\",\n            \"  public abstract int[] ints();\",\n            \"  public abstract Arrays arrays();\",\n            \"\",\n            \"  public static Baz create(int[] ints, Arrays arrays) {\",\n            \"    return new AutoValue_Baz(ints, arrays);\",\n            \"  }\",\n            \"}\");\n    JavaFileObject expectedOutput =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.AutoValue_Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import java.util.Arrays;\",\n            GeneratedImport.importGeneratedAnnotationType(),\n            \"\",\n            \"@Generated(\\\"\" + AutoValueProcessor.class.getName() + \"\\\")\",\n            \"final class AutoValue_Baz extends Baz {\",\n            \"  private final int[] ints;\",\n            \"  private final Arrays arrays;\",\n            \"\",\n            \"  AutoValue_Baz(int[] ints, Arrays arrays) {\",\n            \"    if (ints == null) {\",\n            \"      throw new NullPointerException(\\\"Null ints\\\");\",\n            \"    }\",\n            \"    this.ints = ints;\",\n            \"    if (arrays == null) {\",\n            \"      throw new NullPointerException(\\\"Null arrays\\\");\",\n            \"    }\",\n            \"    this.arrays = arrays;\",\n            \"  }\",\n            \"\",\n            \"  @SuppressWarnings(\\\"mutable\\\")\",\n            \"  @Override public int[] ints() {\",\n            \"    return ints;\",\n            \"  }\",\n            \"\",\n            \"  @Override public Arrays arrays() {\",\n            \"    return arrays;\",\n            \"  }\",\n            \"\",\n            \"  @Override public String toString() {\",\n            \"    return \\\"Baz{\\\"\",\n            \"        + \\\"ints=\\\" + Arrays.toString(ints) + \\\", \\\"\",\n            \"        + \\\"arrays=\\\" + arrays\",\n            \"        + \\\"}\\\";\",\n            \"  }\",\n            \"\",\n            \"  @Override public boolean equals(Object o) {\",\n            \"    if (o == this) {\",\n            \"      return true;\",\n            \"    }\",\n            \"    if (o instanceof Baz) {\",\n            \"      Baz that = (Baz) o;\",\n            \"      return Arrays.equals(this.ints, (that instanceof AutoValue_Baz) \"\n                + \"? ((AutoValue_Baz) that).ints : that.ints())\",\n            \"          && this.arrays.equals(that.arrays());\",\n            \"    }\",\n            \"    return false;\",\n            \"  }\",\n            \"\",\n            \"  @Override public int hashCode() {\",\n            \"    int h$ = 1;\",\n            \"    h$ *= 1000003;\",\n            \"    h$ ^= Arrays.hashCode(ints);\",\n            \"    h$ *= 1000003;\",\n            \"    h$ ^= arrays.hashCode();\",\n            \"    return h$;\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor())\n            .withOptions(\"-A\" + Nullables.NULLABLE_OPTION + \"=\")\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Baz\")\n        .hasSourceEquivalentTo(expectedOutput);\n  }\n\n  @Test\n  public void testNoWarningsFromGenerics() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"@AutoValue\",\n            \"public abstract class Baz<T extends Number, U extends T> {\",\n            \"  public abstract T t();\",\n            \"  public abstract U u();\",\n            \"  public static <T extends Number, U extends T> Baz<T, U> create(T t, U u) {\",\n            \"    return new AutoValue_Baz<T, U>(t, u);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor())\n            .withOptions(\"-Xlint:-processing\", \"-implicit:none\")\n            .compile(javaFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n  }\n\n  @Test\n  public void testNestedParameterizedTypesWithTypeAnnotations() {\n    assume().that(typeAnnotationsWork).isTrue();\n    JavaFileObject annotFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Annot\",\n            \"package foo.bar;\",\n            \"\",\n            \"import java.lang.annotation.ElementType;\",\n            \"import java.lang.annotation.Target;\",\n            \"\",\n            \"@Target(ElementType.TYPE_USE)\",\n            \"public @interface Annot {\",\n            \"  int value();\",\n            \"}\");\n    JavaFileObject outerFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.baz.OuterWithTypeParam\",\n            \"package foo.baz;\",\n            \"\",\n            \"public class OuterWithTypeParam<T extends Number> {\",\n            \"  public class InnerWithTypeParam<U> {}\",\n            \"}\");\n    JavaFileObject nestyFileObject =\n        JavaFileObjects.forSourceLines(\n            \"com.example.Nesty\",\n            \"package com.example;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import foo.bar.Annot;\",\n            \"import foo.baz.OuterWithTypeParam;\",\n            \"\",\n            \"@AutoValue\",\n            \"abstract class Nesty {\",\n            \"  abstract @Annot(1) OuterWithTypeParam<@Annot(2) Double>\",\n            \"      .@Annot(3) InnerWithTypeParam<@Annot(4) String> inner();\",\n            \"\",\n            \"  static Nesty of(\",\n            \"      @Annot(1) OuterWithTypeParam<@Annot(2) Double>\",\n            \"          .@Annot(3) InnerWithTypeParam<@Annot(4) String> inner) {\",\n            \"    return new AutoValue_Nesty(inner);\",\n            \"  }\",\n            \"}\");\n    JavaFileObject expectedOutput =\n        JavaFileObjects.forSourceLines(\n            \"com.example.AutoValue_Nesty\",\n            \"package com.example;\",\n            \"\",\n            \"import foo.bar.Annot;\",\n            \"import foo.baz.OuterWithTypeParam;\",\n            GeneratedImport.importGeneratedAnnotationType(),\n            \"\",\n            \"@Generated(\\\"com.google.auto.value.processor.AutoValueProcessor\\\")\",\n            \"final class AutoValue_Nesty extends Nesty {\",\n            \"  private final @Annot(1) OuterWithTypeParam<@Annot(2) Double>\"\n                + \".@Annot(3) InnerWithTypeParam<@Annot(4) String> inner;\",\n            \"\",\n            \"  AutoValue_Nesty(\",\n            \"      @Annot(1) OuterWithTypeParam<@Annot(2) Double>\"\n                + \".@Annot(3) InnerWithTypeParam<@Annot(4) String> inner) {\",\n            \"    if (inner == null) {\",\n            \"      throw new NullPointerException(\\\"Null inner\\\");\",\n            \"    }\",\n            \"    this.inner = inner;\",\n            \"  }\",\n            \"\",\n            \"  @Override\",\n            \"  @Annot(1) OuterWithTypeParam<@Annot(2) Double>\"\n                + \".@Annot(3) InnerWithTypeParam<@Annot(4) String> inner() {\",\n            \"    return inner;\",\n            \"  }\",\n            \"\",\n            \"  @Override\",\n            \"  public String toString() {\",\n            \"    return \\\"Nesty{\\\"\",\n            \"        + \\\"inner=\\\" + inner\",\n            \"        + \\\"}\\\";\",\n            \"  }\",\n            \"\",\n            \"  @Override\",\n            \"  public boolean equals(Object o) {\",\n            \"    if (o == this) {\",\n            \"      return true;\",\n            \"    }\",\n            \"    if (o instanceof Nesty) {\",\n            \"      Nesty that = (Nesty) o;\",\n            \"      return this.inner.equals(that.inner());\",\n            \"    }\",\n            \"    return false;\",\n            \"  }\",\n            \"\",\n            \"  @Override\",\n            \"  public int hashCode() {\",\n            \"    int h$ = 1;\",\n            \"    h$ *= 1000003;\",\n            \"    h$ ^= inner.hashCode();\",\n            \"    return h$;\",\n            \"  }\",\n            \"}\");\n\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor())\n            .withOptions(\n                \"-Xlint:-processing\", \"-implicit:none\", \"-A\" + Nullables.NULLABLE_OPTION + \"=\")\n            .compile(annotFileObject, outerFileObject, nestyFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"com.example.AutoValue_Nesty\")\n        .hasSourceEquivalentTo(expectedOutput);\n  }\n\n  // Tests that type annotations are correctly copied from the bounds of type parameters in the\n  // @AutoValue class to the bounds of the corresponding parameters in the generated class. For\n  // example, if we have `@AutoValue abstract class Foo<T extends @NullableType Object>`, then the\n  // generated class should be `class AutoValue_Foo<T extends @NullableType Object> extends Foo<T>`.\n  // Some buggy versions of javac do not report type annotations correctly in this context.\n  // AutoValue can't copy them if it can't see them, so we make a special annotation processor to\n  // detect if we are in the presence of this bug and if so we don't fail.\n  @Test\n  public void testTypeParametersWithAnnotationsOnBounds() {\n    @SupportedAnnotationTypes(\"*\")\n    class CompilerBugProcessor extends AbstractProcessor {\n      boolean checkedAnnotationsOnTypeBounds;\n      boolean reportsAnnotationsOnTypeBounds;\n\n      @Override\n      public SourceVersion getSupportedSourceVersion() {\n        return SourceVersion.latestSupported();\n      }\n\n      @Override\n      public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n        if (roundEnv.processingOver()) {\n          TypeElement test = processingEnv.getElementUtils().getTypeElement(\"com.example.Test\");\n          TypeParameterElement t = test.getTypeParameters().get(0);\n          this.checkedAnnotationsOnTypeBounds = true;\n          this.reportsAnnotationsOnTypeBounds =\n              !t.getBounds().get(0).getAnnotationMirrors().isEmpty();\n        }\n        return false;\n      }\n    }\n    CompilerBugProcessor compilerBugProcessor = new CompilerBugProcessor();\n    JavaFileObject nullableTypeFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.NullableType\",\n            \"package foo.bar;\",\n            \"\",\n            \"import java.lang.annotation.ElementType;\",\n            \"import java.lang.annotation.Target;\",\n            \"\",\n            \"@Target(ElementType.TYPE_USE)\",\n            \"public @interface NullableType {}\");\n    JavaFileObject autoValueFileObject =\n        JavaFileObjects.forSourceLines(\n            \"com.example.Test\",\n            \"package com.example;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import foo.bar.NullableType;\",\n            \"\",\n            \"@AutoValue\",\n            \"abstract class Test<T extends @NullableType Object & @NullableType Cloneable> {}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), compilerBugProcessor)\n            .withOptions(\"-Xlint:-processing\", \"-implicit:none\")\n            .compile(nullableTypeFileObject, autoValueFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilerBugProcessor.checkedAnnotationsOnTypeBounds).isTrue();\n    if (compilerBugProcessor.reportsAnnotationsOnTypeBounds) {\n      assertThat(compilation)\n          .generatedSourceFile(\"com.example.AutoValue_Test\")\n          .contentsAsUtf8String()\n          .contains(\n              \"class AutoValue_Test<T extends @NullableType Object & @NullableType Cloneable>\"\n                  + \" extends Test<T> {\");\n    }\n  }\n\n  // In the following few tests, see AutoValueProcessor.validateMethods for why unrecognized\n  // abstract methods provoke only a warning rather than an error. Compilation will fail anyway\n  // because the generated class is not abstract and does not implement the unrecognized methods.\n\n  @Test\n  public void testAbstractVoid() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  public abstract void foo();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadWarningContaining(\n            \"Abstract method is neither a property getter nor a Builder converter\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"void foo()\");\n  }\n\n  @Test\n  public void testAbstractWithParams() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  public abstract int foo(int bar);\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadWarningContaining(\n            \"Abstract method is neither a property getter nor a Builder converter\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"int foo(int bar)\");\n  }\n\n  @Test\n  public void testPrimitiveArrayWarning() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  public abstract byte[] bytes();\",\n            \"  public static Baz create(byte[] bytes) {\",\n            \"    return new AutoValue_Baz(bytes);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation).succeeded();\n    assertThat(compilation)\n        .hadWarningContaining(\n            \"An @AutoValue property that is a primitive array returns the original array\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"byte[] bytes()\");\n  }\n\n  @Test\n  public void testPrimitiveArrayWarningFromParent() {\n    // If the array-valued property is defined by an ancestor then we shouldn't try to attach\n    // the warning to the method that defined it, but rather to the @AutoValue class itself.\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"public abstract class Baz {\",\n            \"  public abstract byte[] bytes();\",\n            \"\",\n            \"  @AutoValue\",\n            \"  public abstract static class BazChild extends Baz {\",\n            \"    public static BazChild create(byte[] bytes) {\",\n            \"      return new AutoValue_Baz_BazChild(bytes);\",\n            \"    }\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation).succeeded();\n    assertThat(compilation)\n        .hadWarningContainingMatch(\n            \"An @AutoValue property that is a primitive array returns the original array\"\n                + \".*foo\\\\.bar\\\\.Baz\\\\.bytes\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"BazChild extends Baz\");\n  }\n\n  @Test\n  public void testPrimitiveArrayWarningSuppressed() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  @SuppressWarnings(\\\"mutable\\\")\",\n            \"  public abstract byte[] bytes();\",\n            \"  public static Baz create(byte[] bytes) {\",\n            \"    return new AutoValue_Baz(bytes);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor())\n            .withOptions(\"-Xlint:-processing\", \"-implicit:none\")\n            .compile(javaFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n  }\n\n  @Test\n  public void autoValueMustBeClass() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public interface Baz {\",\n            \"  String buh();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"@AutoValue only applies to classes\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"interface Baz\");\n  }\n\n  @Test\n  public void autoValueMustNotBeFinal() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public final class Baz {\",\n            \"  public Baz create() {\",\n            \"    return new AutoValue_Baz();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"@AutoValue class must not be final\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"class Baz\");\n  }\n\n  @Test\n  public void autoValueMustBeStatic() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"public class Baz {\",\n            \"  @AutoValue\",\n            \"  public abstract class NotStatic {\",\n            \"    public abstract String buh();\",\n            \"    public NotStatic create(String buh) {\",\n            \"      return new AutoValue_Baz_NotStatic(buh);\",\n            \"    }\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"Nested @AutoValue class must be static\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"abstract class NotStatic\");\n  }\n\n  @Test\n  public void autoValueMustNotBePrivate() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"public class Baz {\",\n            \"  @AutoValue\",\n            \"  private abstract static class Private {\",\n            \"    public abstract String buh();\",\n            \"    public Private create(String buh) {\",\n            \"      return new AutoValue_Baz_Private(buh);\",\n            \"    }\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"@AutoValue class must not be private\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"class Private\");\n  }\n\n  @Test\n  public void autoValueMustBeNotBeNestedInPrivate() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"public class Baz {\",\n            \"  private static class Private {\",\n            \"    @AutoValue\",\n            \"    abstract static class Nested {\",\n            \"      public abstract String buh();\",\n            \"      public Nested create(String buh) {\",\n            \"        return new AutoValue_Baz_Private_Nested(buh);\",\n            \"      }\",\n            \"    }\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"@AutoValue class must not be nested in a private class\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"class Nested\");\n  }\n\n  @Test\n  public void autoValueMustHaveNoArgConstructor() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  Baz(int buh) {}\",\n            \"\",\n            \"  public abstract int buh();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"@AutoValue class must have a non-private no-arg constructor\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"class Baz\");\n  }\n\n  @Test\n  public void autoValueMustHaveVisibleNoArgConstructor() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  private Baz() {}\",\n            \"\",\n            \"  public abstract int buh();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"@AutoValue class must have a non-private no-arg constructor\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"class Baz\");\n  }\n\n  @Test\n  public void noMultidimensionalPrimitiveArrays() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  public abstract int[][] ints();\",\n            \"\",\n            \"  public static Baz create(int[][] ints) {\",\n            \"    return new AutoValue_Baz(ints);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"@AutoValue class cannot define an array-valued property \"\n                + \"unless it is a primitive array\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"int[][] ints()\");\n  }\n\n  @Test\n  public void noObjectArrays() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  public abstract String[] strings();\",\n            \"\",\n            \"  public static Baz create(String[] strings) {\",\n            \"    return new AutoValue_Baz(strings);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"@AutoValue class cannot define an array-valued property \"\n                + \"unless it is a primitive array\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"String[] strings()\");\n  }\n\n  @Test\n  public void annotationOnInterface() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public interface Baz {}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"AutoValue only applies to classes\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"interface Baz\");\n  }\n\n  @Test\n  public void annotationOnEnum() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public enum Baz {}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"AutoValue only applies to classes\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"enum Baz\");\n  }\n\n  @Test\n  public void extendAutoValue() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Outer\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"public class Outer {\",\n            \"  @AutoValue\",\n            \"  static abstract class Parent {\",\n            \"    static Parent create(int randomProperty) {\",\n            \"      return new AutoValue_Outer_Parent(randomProperty);\",\n            \"    }\",\n            \"\",\n            \"    abstract int randomProperty();\",\n            \"  }\",\n            \"\",\n            \"  @AutoValue\",\n            \"  static abstract class Child extends Parent {\",\n            \"    static Child create(int randomProperty) {\",\n            \"      return new AutoValue_Outer_Child(randomProperty);\",\n            \"    }\",\n            \"\",\n            \"    abstract int randomProperty();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"may not extend\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"Child extends Parent\");\n  }\n\n  @Test\n  public void bogusSerialVersionUID() {\n    String[] mistakes = {\n      \"final long serialVersionUID = 1234L\", // not static\n      \"static long serialVersionUID = 1234L\", // not final\n      \"static final Long serialVersionUID = 1234L\", // not long\n      \"static final long serialVersionUID = (Long) 1234L\", // not a compile-time constant\n    };\n    for (String mistake : mistakes) {\n      JavaFileObject javaFileObject =\n          JavaFileObjects.forSourceLines(\n              \"foo.bar.Baz\",\n              \"package foo.bar;\",\n              \"\",\n              \"import com.google.auto.value.AutoValue;\",\n              \"\",\n              \"@AutoValue\",\n              \"public abstract class Baz implements java.io.Serializable {\",\n              \"  \" + mistake + \";\",\n              \"\",\n              \"  public abstract int foo();\",\n              \"}\");\n      Compilation compilation =\n          javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n      expect\n          .about(compilations())\n          .that(compilation)\n          .hadErrorContaining(\"serialVersionUID must be a static final long compile-time constant\")\n          .inFile(javaFileObject)\n          .onLineContaining(mistake);\n    }\n  }\n\n  @Test\n  public void nonExistentSuperclass() {\n    // The main purpose of this test is to check that AutoValueProcessor doesn't crash the\n    // compiler in this case.\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Existent extends NonExistent {\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"NonExistent\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"NonExistent\");\n  }\n\n  @Test\n  public void cannotImplementAnnotation() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.RetentionImpl\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import java.lang.annotation.Retention;\",\n            \"import java.lang.annotation.RetentionPolicy;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class RetentionImpl implements Retention {\",\n            \"  public static Retention create(RetentionPolicy policy) {\",\n            \"    return new AutoValue_RetentionImpl(policy);\",\n            \"  }\",\n            \"\",\n            \"  @Override public Class<? extends Retention> annotationType() {\",\n            \"    return Retention.class;\",\n            \"  }\",\n            \"\",\n            \"  @Override public boolean equals(Object o) {\",\n            \"    return (o instanceof Retention && value().equals((Retention) o).value());\",\n            \"  }\",\n            \"\",\n            \"  @Override public int hashCode() {\",\n            \"    return (\\\"value\\\".hashCode() * 127) ^ value().hashCode();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"may not be used to implement an annotation interface\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"RetentionImpl implements Retention\");\n  }\n\n  @Test\n  public void missingPropertyType() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  public abstract MissingType missingType();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"MissingType\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"MissingType\");\n    assertThat(compilation).hadErrorContaining(\"references undefined types including MissingType\");\n  }\n\n  @Test\n  public void missingGenericPropertyType() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  public abstract MissingType<?> missingType();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"MissingType\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"MissingType\");\n  }\n\n  @Test\n  public void missingComplexGenericPropertyType() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"import java.util.Map;\",\n            \"import java.util.Set;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  public abstract Map<Set<?>, MissingType<?>> missingType();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"MissingType\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"MissingType\");\n  }\n\n  @Test\n  public void missingSuperclassGenericParameter() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<T extends MissingType<?>> {\",\n            \"  public abstract int foo();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"MissingType\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"MissingType\");\n  }\n\n  @Test\n  public void nullablePrimitive() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  @interface Nullable {}\",\n            \"  public abstract @Nullable int foo();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"Primitive types cannot be @Nullable\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"@Nullable int\");\n  }\n\n  @Test\n  public void correctBuilder() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.base.Optional;\",\n            \"import com.google.common.collect.ImmutableMap;\",\n            \"\",\n            \"import java.util.ArrayList;\",\n            \"import java.util.List;\",\n            \"import java.util.Map;\",\n            \"import javax.annotation.Nullable;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<T extends Number> {\",\n            \"  public abstract int anInt();\",\n            \"  @SuppressWarnings(\\\"mutable\\\")\",\n            \"  public abstract byte[] aByteArray();\",\n            \"  @SuppressWarnings(\\\"mutable\\\")\",\n            \"  @Nullable public abstract int[] aNullableIntArray();\",\n            \"  public abstract List<T> aList();\",\n            \"  public abstract ImmutableMap<T, String> anImmutableMap();\",\n            \"  public abstract Optional<String> anOptionalString();\",\n            \"  public abstract NestedAutoValue<T> aNestedAutoValue();\",\n            \"\",\n            \"  public abstract Builder<T> toBuilder();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public abstract static class Builder<T extends Number> {\",\n            \"    public abstract Builder<T> anInt(int x);\",\n            \"    public abstract Builder<T> aByteArray(byte[] x);\",\n            \"    public abstract Builder<T> aNullableIntArray(@Nullable int[] x);\",\n            \"    public abstract Builder<T> aList(List<T> x);\",\n            \"    public abstract Builder<T> anImmutableMap(Map<T, String> x);\",\n            \"    public abstract ImmutableMap.Builder<T, String> anImmutableMapBuilder();\",\n            \"    public abstract Builder<T> anOptionalString(Optional<String> s);\",\n            \"    public abstract Builder<T> anOptionalString(String s);\",\n            \"    public abstract NestedAutoValue.Builder<T> aNestedAutoValueBuilder();\",\n            \"\",\n            \"    public Builder<T> aList(ArrayList<T> x) {\",\n            // ArrayList should not be imported in the generated class.\n            \"      return aList((List<T>) x);\",\n            \"    }\",\n            \"\",\n            \"    public abstract Optional<Integer> anInt();\",\n            \"    public abstract List<T> aList();\",\n            \"    public abstract ImmutableMap<T, String> anImmutableMap();\",\n            \"\",\n            \"    public abstract Baz<T> build();\",\n            \"  }\",\n            \"\",\n            \"  public static <T extends Number> Builder<T> builder() {\",\n            \"    return AutoValue_Baz.builder();\",\n            \"  }\",\n            \"}\");\n    JavaFileObject nestedJavaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.NestedAutoValue\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class NestedAutoValue<T extends Number> {\",\n            \"  public abstract T t();\",\n            \"\",\n            \"  public abstract Builder<T> toBuilder();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public abstract static class Builder<T extends Number> {\",\n            \"    public abstract Builder<T> t(T t);\",\n            \"    public abstract NestedAutoValue<T> build();\",\n            \"  }\",\n            \"\",\n            \"  public static <T extends Number> Builder<T> builder() {\",\n            \"    return AutoValue_NestedAutoValue.builder();\",\n            \"  }\",\n            \"}\");\n    JavaFileObject expectedOutput =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.AutoValue_Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.common.base.Optional;\",\n            \"import com.google.common.collect.ImmutableMap;\",\n            \"import java.util.Arrays;\",\n            \"import java.util.List;\",\n            \"import java.util.Map;\",\n            sorted(\n                GeneratedImport.importGeneratedAnnotationType(),\n                \"import javax.annotation.Nullable;\"),\n            \"\",\n            \"@Generated(\\\"\" + AutoValueProcessor.class.getName() + \"\\\")\",\n            \"final class AutoValue_Baz<T extends Number> extends Baz<T> {\",\n            \"  private final int anInt;\",\n            \"  private final byte[] aByteArray;\",\n            \"  @Nullable\",\n            \"  private final int[] aNullableIntArray;\",\n            \"  private final List<T> aList;\",\n            \"  private final ImmutableMap<T, String> anImmutableMap;\",\n            \"  private final Optional<String> anOptionalString;\",\n            \"  private final NestedAutoValue<T> aNestedAutoValue;\",\n            \"\",\n            \"  private AutoValue_Baz(\",\n            \"      int anInt,\",\n            \"      byte[] aByteArray,\",\n            \"      @Nullable int[] aNullableIntArray,\",\n            \"      List<T> aList,\",\n            \"      ImmutableMap<T, String> anImmutableMap,\",\n            \"      Optional<String> anOptionalString,\",\n            \"      NestedAutoValue<T> aNestedAutoValue) {\",\n            \"    this.anInt = anInt;\",\n            \"    this.aByteArray = aByteArray;\",\n            \"    this.aNullableIntArray = aNullableIntArray;\",\n            \"    this.aList = aList;\",\n            \"    this.anImmutableMap = anImmutableMap;\",\n            \"    this.anOptionalString = anOptionalString;\",\n            \"    this.aNestedAutoValue = aNestedAutoValue;\",\n            \"  }\",\n            \"\",\n            \"  @Override public int anInt() {\",\n            \"    return anInt;\",\n            \"  }\",\n            \"\",\n            \"  @SuppressWarnings(\\\"mutable\\\")\",\n            \"  @Override public byte[] aByteArray() {\",\n            \"    return aByteArray;\",\n            \"  }\",\n            \"\",\n            \"  @SuppressWarnings(\\\"mutable\\\")\",\n            \"  @Nullable\",\n            \"  @Override public int[] aNullableIntArray() {\",\n            \"    return aNullableIntArray;\",\n            \"  }\",\n            \"\",\n            \"  @Override public List<T> aList() {\",\n            \"    return aList;\",\n            \"  }\",\n            \"\",\n            \"  @Override public ImmutableMap<T, String> anImmutableMap() {\",\n            \"    return anImmutableMap;\",\n            \"  }\",\n            \"\",\n            \"  @Override public Optional<String> anOptionalString() {\",\n            \"    return anOptionalString;\",\n            \"  }\",\n            \"\",\n            \"  @Override public NestedAutoValue<T> aNestedAutoValue() {\",\n            \"    return aNestedAutoValue;\",\n            \"  }\",\n            \"\",\n            \"  @Override public String toString() {\",\n            \"    return \\\"Baz{\\\"\",\n            \"        + \\\"anInt=\\\" + anInt + \\\", \\\"\",\n            \"        + \\\"aByteArray=\\\" + Arrays.toString(aByteArray) + \\\", \\\"\",\n            \"        + \\\"aNullableIntArray=\\\" + Arrays.toString(aNullableIntArray) + \\\", \\\"\",\n            \"        + \\\"aList=\\\" + aList + \\\", \\\"\",\n            \"        + \\\"anImmutableMap=\\\" + anImmutableMap + \\\", \\\"\",\n            \"        + \\\"anOptionalString=\\\" + anOptionalString + \\\", \\\"\",\n            \"        + \\\"aNestedAutoValue=\\\" + aNestedAutoValue\",\n            \"        + \\\"}\\\";\",\n            \"  }\",\n            \"\",\n            \"  @Override public boolean equals(Object o) {\",\n            \"    if (o == this) {\",\n            \"      return true;\",\n            \"    }\",\n            \"    if (o instanceof Baz) {\",\n            \"      Baz<?> that = (Baz<?>) o;\",\n            \"      return this.anInt == that.anInt()\",\n            \"          && Arrays.equals(this.aByteArray, \"\n                + \"(that instanceof AutoValue_Baz) \"\n                + \"? ((AutoValue_Baz<?>) that).aByteArray : that.aByteArray())\",\n            \"          && Arrays.equals(this.aNullableIntArray, \"\n                + \"(that instanceof AutoValue_Baz) \"\n                + \"? ((AutoValue_Baz<?>) that).aNullableIntArray : that.aNullableIntArray())\",\n            \"          && this.aList.equals(that.aList())\",\n            \"          && this.anImmutableMap.equals(that.anImmutableMap())\",\n            \"          && this.anOptionalString.equals(that.anOptionalString())\",\n            \"          && this.aNestedAutoValue.equals(that.aNestedAutoValue());\",\n            \"    }\",\n            \"    return false;\",\n            \"  }\",\n            \"\",\n            \"  @Override public int hashCode() {\",\n            \"    int h$ = 1;\",\n            \"    h$ *= 1000003;\",\n            \"    h$ ^= anInt;\",\n            \"    h$ *= 1000003;\",\n            \"    h$ ^= Arrays.hashCode(aByteArray);\",\n            \"    h$ *= 1000003;\",\n            \"    h$ ^= Arrays.hashCode(aNullableIntArray);\",\n            \"    h$ *= 1000003;\",\n            \"    h$ ^= aList.hashCode();\",\n            \"    h$ *= 1000003;\",\n            \"    h$ ^= anImmutableMap.hashCode();\",\n            \"    h$ *= 1000003;\",\n            \"    h$ ^= anOptionalString.hashCode();\",\n            \"    h$ *= 1000003;\",\n            \"    h$ ^= aNestedAutoValue.hashCode();\",\n            \"    return h$;\",\n            \"  }\",\n            \"\",\n            \"  @Override public Baz.Builder<T> toBuilder() {\",\n            \"    return new AutoValue_Baz.Builder<T>(this);\",\n            \"  }\",\n            \"\",\n            \"  static final class Builder<T extends Number> extends Baz.Builder<T> {\",\n            \"    private int anInt;\",\n            \"    private byte[] aByteArray;\",\n            \"    private int[] aNullableIntArray;\",\n            \"    private List<T> aList;\",\n            \"    private ImmutableMap.Builder<T, String> anImmutableMapBuilder$;\",\n            \"    private ImmutableMap<T, String> anImmutableMap;\",\n            \"    private Optional<String> anOptionalString = Optional.absent();\",\n            \"    private NestedAutoValue.Builder<T> aNestedAutoValueBuilder$;\",\n            \"    private NestedAutoValue<T> aNestedAutoValue;\",\n            \"    private byte set$0;\",\n            \"\",\n            \"    Builder() {\",\n            \"    }\",\n            \"\",\n            \"    Builder(Baz<T> source) {\",\n            \"      this.anInt = source.anInt();\",\n            \"      this.aByteArray = source.aByteArray();\",\n            \"      this.aNullableIntArray = source.aNullableIntArray();\",\n            \"      this.aList = source.aList();\",\n            \"      this.anImmutableMap = source.anImmutableMap();\",\n            \"      this.anOptionalString = source.anOptionalString();\",\n            \"      this.aNestedAutoValue = source.aNestedAutoValue();\",\n            \"      set$0 = (byte) 1;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public Baz.Builder<T> anInt(int anInt) {\",\n            \"      this.anInt = anInt;\",\n            \"      set$0 |= (byte) 1;\",\n            \"      return this;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public Optional<Integer> anInt() {\",\n            \"      if ((set$0 & 1) == 0) {\",\n            \"        return Optional.absent();\",\n            \"      }\",\n            \"      return Optional.of(anInt);\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public Baz.Builder<T> aByteArray(byte[] aByteArray) {\",\n            \"      if (aByteArray == null) {\",\n            \"        throw new NullPointerException(\\\"Null aByteArray\\\");\",\n            \"      }\",\n            \"      this.aByteArray = aByteArray;\",\n            \"      return this;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public Baz.Builder<T> aNullableIntArray(@Nullable int[] aNullableIntArray) {\",\n            \"      this.aNullableIntArray = aNullableIntArray;\",\n            \"      return this;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public Baz.Builder<T> aList(List<T> aList) {\",\n            \"      if (aList == null) {\",\n            \"        throw new NullPointerException(\\\"Null aList\\\");\",\n            \"      }\",\n            \"      this.aList = aList;\",\n            \"      return this;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public List<T> aList() {\",\n            \"      if (this.aList == null) {\",\n            \"        throw new IllegalStateException(\\\"Property \\\\\\\"aList\\\\\\\" has not been set\\\");\",\n            \"      }\",\n            \"      return aList;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public Baz.Builder<T> anImmutableMap(Map<T, String> anImmutableMap) {\",\n            \"      if (anImmutableMapBuilder$ != null) {\",\n            \"        throw new IllegalStateException(\"\n                + \"\\\"Cannot set anImmutableMap after calling anImmutableMapBuilder()\\\");\",\n            \"      }\",\n            \"      this.anImmutableMap = ImmutableMap.copyOf(anImmutableMap);\",\n            \"      return this;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public ImmutableMap.Builder<T, String> anImmutableMapBuilder() {\",\n            \"      if (anImmutableMapBuilder$ == null) {\",\n            \"        if (anImmutableMap == null) {\",\n            \"          anImmutableMapBuilder$ = ImmutableMap.builder();\",\n            \"        } else {\",\n            \"          anImmutableMapBuilder$ = ImmutableMap.builder();\",\n            \"          anImmutableMapBuilder$.putAll(anImmutableMap);\",\n            \"          anImmutableMap = null;\",\n            \"        }\",\n            \"      }\",\n            \"      return anImmutableMapBuilder$;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public ImmutableMap<T, String> anImmutableMap() {\",\n            \"      if (anImmutableMapBuilder$ != null) {\",\n            \"        return anImmutableMapBuilder$.buildOrThrow();\",\n            \"      }\",\n            \"      if (anImmutableMap == null) {\",\n            \"        anImmutableMap = ImmutableMap.of();\",\n            \"      }\",\n            \"      return anImmutableMap;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public Baz.Builder<T> anOptionalString(Optional<String> anOptionalString) {\",\n            \"      if (anOptionalString == null) {\",\n            \"        throw new NullPointerException(\\\"Null anOptionalString\\\");\",\n            \"      }\",\n            \"      this.anOptionalString = anOptionalString;\",\n            \"      return this;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public Baz.Builder<T> anOptionalString(String anOptionalString) {\",\n            \"      this.anOptionalString = Optional.of(anOptionalString);\",\n            \"      return this;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public NestedAutoValue.Builder<T> aNestedAutoValueBuilder() {\",\n            \"      if (aNestedAutoValueBuilder$ == null) {\",\n            \"        if (aNestedAutoValue == null) {\",\n            \"          aNestedAutoValueBuilder$ = NestedAutoValue.builder();\",\n            \"        } else {\",\n            \"          aNestedAutoValueBuilder$ = aNestedAutoValue.toBuilder();\",\n            \"          aNestedAutoValue = null;\",\n            \"        }\",\n            \"      }\",\n            \"      return aNestedAutoValueBuilder$;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public Baz<T> build() {\",\n            \"      if (anImmutableMapBuilder$ != null) {\",\n            \"        this.anImmutableMap = anImmutableMapBuilder$.buildOrThrow();\",\n            \"      } else if (this.anImmutableMap == null) {\",\n            \"        this.anImmutableMap = ImmutableMap.of();\",\n            \"      }\",\n            \"      if (aNestedAutoValueBuilder$ != null) {\",\n            \"        this.aNestedAutoValue = aNestedAutoValueBuilder$.build();\",\n            \"      } else if (this.aNestedAutoValue == null) {\",\n            \"        NestedAutoValue.Builder<T> aNestedAutoValue$builder = \"\n                + \"NestedAutoValue.builder();\",\n            \"        this.aNestedAutoValue = aNestedAutoValue$builder.build();\",\n            \"      }\",\n            \"      if (set$0 != 1\",\n            \"          || this.aByteArray == null\",\n            \"          || this.aList == null) {\",\n            \"        StringBuilder missing = new StringBuilder();\",\n            \"        if ((set$0 & 1) == 0) {\",\n            \"            missing.append(\\\" anInt\\\");\",\n            \"        }\",\n            \"        if (this.aByteArray == null) {\",\n            \"          missing.append(\\\" aByteArray\\\");\",\n            \"        }\",\n            \"        if (this.aList == null) {\",\n            \"          missing.append(\\\" aList\\\");\",\n            \"        }\",\n            \"        throw new IllegalStateException(\\\"Missing required properties:\\\" + missing);\",\n            \"      }\",\n            \"      return new AutoValue_Baz<T>(\",\n            \"          this.anInt,\",\n            \"          this.aByteArray,\",\n            \"          this.aNullableIntArray,\",\n            \"          this.aList,\",\n            \"          this.anImmutableMap,\",\n            \"          this.anOptionalString,\",\n            \"          this.aNestedAutoValue);\",\n            \"    }\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor())\n            .withOptions(\n                \"-Xlint:-processing\", \"-implicit:none\", \"-A\" + Nullables.NULLABLE_OPTION + \"=\")\n            .compile(javaFileObject, nestedJavaFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Baz\")\n        .hasSourceEquivalentTo(expectedOutput);\n  }\n\n  @Test\n  public void builderWithNullableTypeAnnotation() {\n    assume().that(typeAnnotationsWork).isTrue();\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.base.Optional;\",\n            \"import com.google.common.collect.ImmutableMap;\",\n            \"\",\n            \"import java.util.ArrayList;\",\n            \"import java.util.List;\",\n            \"import java.util.Map;\",\n            \"import org.jspecify.annotations.Nullable;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<T extends Number> {\",\n            \"  public abstract int anInt();\",\n            \"  @SuppressWarnings(\\\"mutable\\\")\",\n            \"  public abstract byte[] aByteArray();\",\n            \"  @SuppressWarnings(\\\"mutable\\\")\",\n            \"  public abstract int @Nullable [] aNullableIntArray();\",\n            \"  public abstract List<T> aList();\",\n            \"  public abstract ImmutableMap<T, String> anImmutableMap();\",\n            \"  public abstract Optional<String> anOptionalString();\",\n            \"\",\n            \"  public abstract Builder<T> toBuilder();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public abstract static class Builder<T extends Number> {\",\n            \"    public abstract Builder<T> anInt(int x);\",\n            \"    public abstract Builder<T> aByteArray(byte[] x);\",\n            \"    public abstract Builder<T> aNullableIntArray(int @Nullable [] x);\",\n            \"    public abstract Builder<T> aList(List<T> x);\",\n            \"    public abstract Builder<T> anImmutableMap(Map<T, String> x);\",\n            \"    public abstract ImmutableMap.Builder<T, String> anImmutableMapBuilder();\",\n            \"    public abstract Builder<T> anOptionalString(Optional<String> s);\",\n            \"    public abstract Baz<T> build();\",\n            \"  }\",\n            \"\",\n            \"  public static <T extends Number> Builder<T> builder() {\",\n            \"    return AutoValue_Baz.builder();\",\n            \"  }\",\n            \"}\");\n    JavaFileObject expectedOutput =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.AutoValue_Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.common.base.Optional;\",\n            \"import com.google.common.collect.ImmutableMap;\",\n            \"import java.util.Arrays;\",\n            \"import java.util.List;\",\n            \"import java.util.Map;\",\n            sorted(\n                GeneratedImport.importGeneratedAnnotationType(),\n                \"import org.jspecify.annotations.Nullable;\"),\n            \"\",\n            \"@Generated(\\\"\" + AutoValueProcessor.class.getName() + \"\\\")\",\n            \"final class AutoValue_Baz<T extends Number> extends Baz<T> {\",\n            \"  private final int anInt;\",\n            \"  private final byte[] aByteArray;\",\n            \"  private final int @Nullable [] aNullableIntArray;\",\n            \"  private final List<T> aList;\",\n            \"  private final ImmutableMap<T, String> anImmutableMap;\",\n            \"  private final Optional<String> anOptionalString;\",\n            \"\",\n            \"  private AutoValue_Baz(\",\n            \"      int anInt,\",\n            \"      byte[] aByteArray,\",\n            \"      int @Nullable [] aNullableIntArray,\",\n            \"      List<T> aList,\",\n            \"      ImmutableMap<T, String> anImmutableMap,\",\n            \"      Optional<String> anOptionalString) {\",\n            \"    this.anInt = anInt;\",\n            \"    this.aByteArray = aByteArray;\",\n            \"    this.aNullableIntArray = aNullableIntArray;\",\n            \"    this.aList = aList;\",\n            \"    this.anImmutableMap = anImmutableMap;\",\n            \"    this.anOptionalString = anOptionalString;\",\n            \"  }\",\n            \"\",\n            \"  @Override public int anInt() {\",\n            \"    return anInt;\",\n            \"  }\",\n            \"\",\n            \"  @SuppressWarnings(\\\"mutable\\\")\",\n            \"  @Override public byte[] aByteArray() {\",\n            \"    return aByteArray;\",\n            \"  }\",\n            \"\",\n            \"  @SuppressWarnings(\\\"mutable\\\")\",\n            \"  @Override public int @Nullable [] aNullableIntArray() {\",\n            \"    return aNullableIntArray;\",\n            \"  }\",\n            \"\",\n            \"  @Override public List<T> aList() {\",\n            \"    return aList;\",\n            \"  }\",\n            \"\",\n            \"  @Override public ImmutableMap<T, String> anImmutableMap() {\",\n            \"    return anImmutableMap;\",\n            \"  }\",\n            \"\",\n            \"  @Override public Optional<String> anOptionalString() {\",\n            \"    return anOptionalString;\",\n            \"  }\",\n            \"\",\n            \"  @Override public String toString() {\",\n            \"    return \\\"Baz{\\\"\",\n            \"        + \\\"anInt=\\\" + anInt + \\\", \\\"\",\n            \"        + \\\"aByteArray=\\\" + Arrays.toString(aByteArray) + \\\", \\\"\",\n            \"        + \\\"aNullableIntArray=\\\" + Arrays.toString(aNullableIntArray) + \\\", \\\"\",\n            \"        + \\\"aList=\\\" + aList + \\\", \\\"\",\n            \"        + \\\"anImmutableMap=\\\" + anImmutableMap + \\\", \\\"\",\n            \"        + \\\"anOptionalString=\\\" + anOptionalString\",\n            \"        + \\\"}\\\";\",\n            \"  }\",\n            \"\",\n            \"  @Override public boolean equals(@Nullable Object o) {\",\n            \"    if (o == this) {\",\n            \"      return true;\",\n            \"    }\",\n            \"    if (o instanceof Baz) {\",\n            \"      Baz<?> that = (Baz<?>) o;\",\n            \"      return this.anInt == that.anInt()\",\n            \"          && Arrays.equals(this.aByteArray, \"\n                + \"(that instanceof AutoValue_Baz) \"\n                + \"? ((AutoValue_Baz<?>) that).aByteArray : that.aByteArray())\",\n            \"          && Arrays.equals(this.aNullableIntArray, \"\n                + \"(that instanceof AutoValue_Baz) \"\n                + \"? ((AutoValue_Baz<?>) that).aNullableIntArray : that.aNullableIntArray())\",\n            \"          && this.aList.equals(that.aList())\",\n            \"          && this.anImmutableMap.equals(that.anImmutableMap())\",\n            \"          && this.anOptionalString.equals(that.anOptionalString());\",\n            \"    }\",\n            \"    return false;\",\n            \"  }\",\n            \"\",\n            \"  @Override public int hashCode() {\",\n            \"    int h$ = 1;\",\n            \"    h$ *= 1000003;\",\n            \"    h$ ^= anInt;\",\n            \"    h$ *= 1000003;\",\n            \"    h$ ^= Arrays.hashCode(aByteArray);\",\n            \"    h$ *= 1000003;\",\n            \"    h$ ^= Arrays.hashCode(aNullableIntArray);\",\n            \"    h$ *= 1000003;\",\n            \"    h$ ^= aList.hashCode();\",\n            \"    h$ *= 1000003;\",\n            \"    h$ ^= anImmutableMap.hashCode();\",\n            \"    h$ *= 1000003;\",\n            \"    h$ ^= anOptionalString.hashCode();\",\n            \"    return h$;\",\n            \"  }\",\n            \"\",\n            \"  @Override public Baz.Builder<T> toBuilder() {\",\n            \"    return new AutoValue_Baz.Builder<T>(this);\",\n            \"  }\",\n            \"\",\n            \"  static final class Builder<T extends Number> extends Baz.Builder<T> {\",\n            \"    private int anInt;\",\n            \"    private byte @Nullable [] aByteArray;\",\n            \"    private int @Nullable [] aNullableIntArray;\",\n            \"    private @Nullable List<T> aList;\",\n            \"    private ImmutableMap.@Nullable Builder<T, String> anImmutableMapBuilder$;\",\n            \"    private @Nullable ImmutableMap<T, String> anImmutableMap;\",\n            \"    private Optional<String> anOptionalString = Optional.absent();\",\n            \"    private byte set$0;\",\n            \"\",\n            \"    Builder() {\",\n            \"    }\",\n            \"\",\n            \"    Builder(Baz<T> source) {\",\n            \"      this.anInt = source.anInt();\",\n            \"      this.aByteArray = source.aByteArray();\",\n            \"      this.aNullableIntArray = source.aNullableIntArray();\",\n            \"      this.aList = source.aList();\",\n            \"      this.anImmutableMap = source.anImmutableMap();\",\n            \"      this.anOptionalString = source.anOptionalString();\",\n            \"      set$0 = (byte) 1;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public Baz.Builder<T> anInt(int anInt) {\",\n            \"      this.anInt = anInt;\",\n            \"      set$0 |= (byte) 1;\",\n            \"      return this;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public Baz.Builder<T> aByteArray(byte[] aByteArray) {\",\n            \"      if (aByteArray == null) {\",\n            \"        throw new NullPointerException(\\\"Null aByteArray\\\");\",\n            \"      }\",\n            \"      this.aByteArray = aByteArray;\",\n            \"      return this;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public Baz.Builder<T> aNullableIntArray(int @Nullable [] aNullableIntArray) {\",\n            \"      this.aNullableIntArray = aNullableIntArray;\",\n            \"      return this;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public Baz.Builder<T> aList(List<T> aList) {\",\n            \"      if (aList == null) {\",\n            \"        throw new NullPointerException(\\\"Null aList\\\");\",\n            \"      }\",\n            \"      this.aList = aList;\",\n            \"      return this;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public Baz.Builder<T> anImmutableMap(Map<T, String> anImmutableMap) {\",\n            \"      if (anImmutableMapBuilder$ != null) {\",\n            \"        throw new IllegalStateException(\"\n                + \"\\\"Cannot set anImmutableMap after calling anImmutableMapBuilder()\\\");\",\n            \"      }\",\n            \"      this.anImmutableMap = ImmutableMap.copyOf(anImmutableMap);\",\n            \"      return this;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public ImmutableMap.Builder<T, String> anImmutableMapBuilder() {\",\n            \"      if (anImmutableMapBuilder$ == null) {\",\n            \"        if (anImmutableMap == null) {\",\n            \"          anImmutableMapBuilder$ = ImmutableMap.builder();\",\n            \"        } else {\",\n            \"          anImmutableMapBuilder$ = ImmutableMap.builder();\",\n            \"          anImmutableMapBuilder$.putAll(anImmutableMap);\",\n            \"          anImmutableMap = null;\",\n            \"        }\",\n            \"      }\",\n            \"      return anImmutableMapBuilder$;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public Baz.Builder<T> anOptionalString(Optional<String> anOptionalString) {\",\n            \"      if (anOptionalString == null) {\",\n            \"        throw new NullPointerException(\\\"Null anOptionalString\\\");\",\n            \"      }\",\n            \"      this.anOptionalString = anOptionalString;\",\n            \"      return this;\",\n            \"    }\",\n            \"\",\n            \"    @Override\",\n            \"    public Baz<T> build() {\",\n            \"      if (anImmutableMapBuilder$ != null) {\",\n            \"        this.anImmutableMap = anImmutableMapBuilder$.buildOrThrow();\",\n            \"      } else if (this.anImmutableMap == null) {\",\n            \"        this.anImmutableMap = ImmutableMap.of();\",\n            \"      }\",\n            \"      if (set$0 != 1\",\n            \"          || this.aByteArray == null\",\n            \"          || this.aList == null) {\",\n            \"        StringBuilder missing = new StringBuilder();\",\n            \"        if ((set$0 & 1) == 0) {\",\n            \"            missing.append(\\\" anInt\\\");\",\n            \"        }\",\n            \"        if (this.aByteArray == null) {\",\n            \"          missing.append(\\\" aByteArray\\\");\",\n            \"        }\",\n            \"        if (this.aList == null) {\",\n            \"          missing.append(\\\" aList\\\");\",\n            \"        }\",\n            \"        throw new IllegalStateException(\\\"Missing required properties:\\\" + missing);\",\n            \"      }\",\n            \"      return new AutoValue_Baz<T>(\",\n            \"          this.anInt,\",\n            \"          this.aByteArray,\",\n            \"          this.aNullableIntArray,\",\n            \"          this.aList,\",\n            \"          this.anImmutableMap,\",\n            \"          this.anOptionalString);\",\n            \"    }\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor())\n            .withOptions(\n                \"-Xlint:-processing\",\n                \"-implicit:none\",\n                \"-A\" + Nullables.NULLABLE_OPTION + \"=org.jspecify.annotations.Nullable\")\n            .compile(javaFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Baz\")\n        .hasSourceEquivalentTo(expectedOutput);\n  }\n\n  @Test\n  public void autoValueBuilderOnTopLevelClass() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Builder\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue.Builder\",\n            \"public interface Builder {\",\n            \"  Builder foo(int x);\",\n            \"  Object build();\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"can only be applied to a class or interface inside\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"public interface Builder\");\n  }\n\n  @Test\n  public void autoValueBuilderNotInsideAutoValue() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"public abstract class Baz {\",\n            \"  abstract int foo();\",\n            \"\",\n            \"  static Builder builder() {\",\n            \"    return new AutoValue_Baz.Builder();\",\n            \"  }\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Builder foo(int x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"can only be applied to a class or interface inside\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"public interface Builder\");\n  }\n\n  @Test\n  public void autoValueBuilderNotStatic() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Example\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"class Example {\",\n            \"  @AutoValue\",\n            \"  abstract static class Baz {\",\n            \"    abstract int foo();\",\n            \"\",\n            \"    static Builder builder() {\",\n            \"      return new AutoValue_Example_Baz.Builder();\",\n            \"    }\",\n            \"\",\n            \"    @AutoValue.Builder\",\n            \"    abstract class Builder {\",\n            \"      abstract Builder foo(int x);\",\n            \"      abstract Baz build();\",\n            \"    }\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"@AutoValue.Builder cannot be applied to a non-static class\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"abstract class Builder\");\n  }\n\n  @Test\n  public void autoValueBuilderMustHaveNoArgConstructor() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Example\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"class Example {\",\n            \"  @AutoValue\",\n            \"  abstract static class Baz {\",\n            \"    abstract int foo();\",\n            \"\",\n            \"    static Builder builder() {\",\n            \"      return new AutoValue_Example_Baz.Builder();\",\n            \"    }\",\n            \"\",\n            \"    @AutoValue.Builder\",\n            \"    abstract static class Builder {\",\n            \"      Builder(int defaultFoo) {}\",\n            \"      abstract Builder foo(int x);\",\n            \"      abstract Baz build();\",\n            \"    }\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"@AutoValue.Builder class must have a non-private no-arg constructor\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"class Builder\");\n  }\n\n  @Test\n  public void autoValueBuilderOnEnum() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract int foo();\",\n            \"\",\n            \"  static Builder builder() {\",\n            \"    return null;\",\n            \"  }\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public enum Builder {}\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"can only apply to a class or an interface\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"public enum Builder\");\n  }\n\n  @Test\n  public void autoValueBuilderDuplicate() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder1 {\",\n            \"    Baz build();\",\n            \"  }\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder2 {\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"already has a Builder: foo.bar.Baz.Builder1\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"public interface Builder2\");\n  }\n\n  @Test\n  public void autoValueBuilderMissingSetter() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract int blim();\",\n            \"  abstract String blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Builder blam(String x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"with this signature: foo.bar.Baz.Builder blim(int)\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"public interface Builder\");\n  }\n\n  @Test\n  public void autoValueBuilderMissingSetterUsingSetPrefix() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract int blim();\",\n            \"  abstract String blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Builder setBlam(String x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"with this signature: foo.bar.Baz.Builder setBlim(int)\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"public interface Builder\");\n  }\n\n  @Test\n  public void autoValueBuilderWrongTypeSetter() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract int blim();\",\n            \"  abstract String blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Builder blim(String x);\",\n            \"    Builder blam(String x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Parameter type java.lang.String of setter method should be int \"\n                + \"to match property method foo.bar.Baz.blim()\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"Builder blim(String x)\");\n  }\n\n  @Test\n  public void autoValueBuilderSetterReturnsNullable() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import javax.annotation.Nullable;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    @Nullable Builder blam(String x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadWarningContaining(\n            \"Setter methods always return the Builder so @Nullable is not appropriate\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"Builder blam(String x)\");\n  }\n\n  @Test\n  public void autoValueBuilderWrongTypeSetterWithCopyOf() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.collect.ImmutableList;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String blim();\",\n            \"  abstract ImmutableList<String> blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Builder blim(String x);\",\n            \"    Builder blam(String x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Parameter type java.lang.String of setter method should be\"\n                + \" com.google.common.collect.ImmutableList<java.lang.String> to match property\"\n                + \" method foo.bar.Baz.blam(), or it should be a type that can be passed to\"\n                + \" ImmutableList.copyOf\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"Builder blam(String x)\");\n  }\n\n  @Test\n  public void autoValueBuilderWrongTypeSetterWithCopyOfGenericallyWrong() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.collect.ImmutableList;\",\n            \"import java.util.Collection;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String blim();\",\n            \"  abstract ImmutableList<String> blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Builder blim(String x);\",\n            \"    Builder blam(Collection<Integer> x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Parameter type java.util.Collection<java.lang.Integer> of setter method should be\"\n                + \" com.google.common.collect.ImmutableList<java.lang.String> to match property\"\n                + \" method foo.bar.Baz.blam(), or it should be a type that can be passed to\"\n                + \" ImmutableList.copyOf to produce\"\n                + \" com.google.common.collect.ImmutableList<java.lang.String>\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"Builder blam(Collection<Integer> x)\");\n  }\n\n  @Test\n  public void autoValueBuilderWrongTypeSetterWithGetPrefix() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract int getBlim();\",\n            \"  abstract String getBlam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Builder blim(String x);\",\n            \"    Builder blam(String x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Parameter type java.lang.String of setter method should be int \"\n                + \"to match property method foo.bar.Baz.getBlim()\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"Builder blim(String x)\");\n  }\n\n  @Test\n  public void autoValueBuilderNullableSetterForNonNullable() {\n    JavaFileObject nullableFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Nullable\",\n            \"package foo.bar;\",\n            \"\",\n            \"import java.lang.annotation.ElementType;\",\n            \"import java.lang.annotation.Target;\",\n            \"\",\n            \"@Target(ElementType.TYPE_USE)\",\n            \"public @interface Nullable {}\");\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String notNull();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Builder setNotNull(@Nullable String x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject, nullableFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Parameter of setter method is @Nullable but property method\"\n                + \" foo.bar.Baz.notNull() is not\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"setNotNull\");\n  }\n\n  // Check that we get a helpful error message if some of your properties look like getters but\n  // others don't.\n  @Test\n  public void autoValueBuilderBeansConfusion() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Item\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Item {\",\n            \"  abstract String getTitle();\",\n            \"  abstract boolean hasThumbnail();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Builder setTitle(String title);\",\n            \"    Builder setHasThumbnail(boolean t);\",\n            \"    Item build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Method setTitle does not correspond to a property method of foo.bar.Item\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"Builder setTitle(String title)\");\n    assertThat(compilation)\n        .hadNoteContaining(\"hasThumbnail\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"Builder setTitle(String title)\");\n  }\n\n  @Test\n  public void autoValueBuilderExtraSetter() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Builder blim(int x);\",\n            \"    Builder blam(String x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"Method blim does not correspond to a property method of foo.bar.Baz\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"Builder blim(int x)\");\n  }\n\n  @Test\n  public void autoValueBuilderSetPrefixAndNoSetPrefix() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract int blim();\",\n            \"  abstract String blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Builder blim(int x);\",\n            \"    Builder setBlam(String x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"If any setter methods use the setFoo convention then all must\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"Builder blim(int x)\");\n  }\n\n  @Test\n  public void autoValueBuilderSetterReturnType() {\n    // We do allow the return type of a setter to be a supertype of the builder type, to support\n    // step builders. But we don't allow it to be Object.\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract int blim();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Object blim(int x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"Setter methods must return foo.bar.Baz.Builder\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"Object blim(int x)\");\n  }\n\n  @Test\n  public void autoValueBuilderWrongTypeGetter() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<T, U> {\",\n            \"  abstract T blim();\",\n            \"  abstract U blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<T, U> {\",\n            \"    Builder<T, U> blim(T x);\",\n            \"    Builder<T, U> blam(U x);\",\n            \"    T blim();\",\n            \"    T blam();\",\n            \"    Baz<T, U> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContainingMatch(\n            \"Method matches a property of foo\\\\.bar\\\\.Baz<T, ?U> but has return type T instead of\"\n                + \" U\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"T blam()\");\n    // The <T, ?U> is because we're depending on TypeMirror.toString(), and the JDK actually spells\n    // this as <T,U> with no space. While it's not completely sound to expect a given string from\n    // TypeMirror.toString(), in practice it's hard to imagine that it would be anything other\n    // than \"foo.bar.Baz<T,U>\" or \"foo.bar.Baz<T, U>\" given the specification.\n  }\n\n  @Test\n  public void autoValueBuilderPropertyBuilderInvalidType() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<T, U> {\",\n            \"  abstract String blim();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<T, U> {\",\n            \"    StringBuilder blimBuilder();\",\n            \"    Baz<T, U> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Method looks like a property builder, but it returns java.lang.StringBuilder which \"\n                + \"does not have a non-static build() or buildOrThrow() method\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"StringBuilder blimBuilder()\");\n  }\n\n  @Test\n  public void autoValueBuilderPropertyBuilderNullable() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.collect.ImmutableList;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<T, U> {\",\n            \"  @interface Nullable {}\",\n            \"  abstract @Nullable ImmutableList<String> strings();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<T, U> {\",\n            \"    ImmutableList.Builder<String> stringsBuilder();\",\n            \"    Baz<T, U> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"Property strings is @Nullable so it cannot have a property builder\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"stringsBuilder()\");\n  }\n\n  @Test\n  public void autoValueBuilderPropertyBuilderNullableType() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.collect.ImmutableList;\",\n            \"import java.lang.annotation.ElementType;\",\n            \"import java.lang.annotation.Target;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<T, U> {\",\n            \"  @Target(ElementType.TYPE_USE)\",\n            \"  @interface Nullable {}\",\n            \"  abstract @Nullable ImmutableList<String> strings();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<T, U> {\",\n            \"    ImmutableList.Builder<String> stringsBuilder();\",\n            \"    Baz<T, U> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"Property strings is @Nullable so it cannot have a property builder\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"stringsBuilder()\");\n  }\n\n  @Test\n  public void autoValueBuilderPropertyBuilderWrongCollectionType() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.collect.ImmutableList;\",\n            \"import com.google.common.collect.ImmutableSet;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<T, U> {\",\n            \"  abstract ImmutableList<T> blim();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<T, U> {\",\n            \"    ImmutableSet.Builder<T> blimBuilder();\",\n            \"    Baz<T, U> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Property builder for blim has type com.google.common.collect.ImmutableSet.Builder \"\n                + \"whose build() method returns com.google.common.collect.ImmutableSet<T> \"\n                + \"instead of com.google.common.collect.ImmutableList<T>\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"ImmutableSet.Builder<T> blimBuilder()\");\n  }\n\n  @Test\n  public void autoValueBuilderPropertyBuilderWeirdBuilderType() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.collect.ImmutableSet;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<T, U> {\",\n            \"  abstract Integer blim();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<T, U> {\",\n            \"    int blimBuilder();\",\n            \"    Baz<T, U> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Method looks like a property builder, but its return type is not a class or interface\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"int blimBuilder()\");\n  }\n\n  @Test\n  public void autoValueBuilderPropertyBuilderWeirdBuiltType() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.collect.ImmutableSet;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<T, U> {\",\n            \"  abstract int blim();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<T, U> {\",\n            \"    Integer blimBuilder();\",\n            \"    Baz<T, U> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Method looks like a property builder, but the type of property blim is not a class \"\n                + \"or interface\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"Integer blimBuilder()\");\n  }\n\n  @Test\n  public void autoValueBuilderPropertyBuilderHasNoBuild() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.collect.ImmutableSet;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<T, U> {\",\n            \"  abstract String blim();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<T, U> {\",\n            \"    StringBuilder blimBuilder();\",\n            \"    Baz<T, U> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Method looks like a property builder, but it returns java.lang.StringBuilder which \"\n                + \"does not have a non-static build() or buildOrThrow() method\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"StringBuilder blimBuilder()\");\n  }\n\n  @Test\n  public void autoValueBuilderPropertyBuilderHasStaticBuild() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.collect.ImmutableSet;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<T, U> {\",\n            \"  abstract String blim();\",\n            \"\",\n            \"  public static class StringFactory {\",\n            \"    public static String build() {\",\n            \"      return null;\",\n            \"    }\",\n            \"  }\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<T, U> {\",\n            \"    StringFactory blimBuilder();\",\n            \"    Baz<T, U> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Method looks like a property builder, but it returns foo.bar.Baz.StringFactory which \"\n                + \"does not have a non-static build() or buildOrThrow() method\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"StringFactory blimBuilder()\");\n  }\n\n  @Test\n  public void autoValueBuilderPropertyBuilderReturnsWrongType() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.collect.ImmutableSet;\",\n            \"import java.util.List;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<E> {\",\n            \"  abstract List<E> blim();\",\n            \"\",\n            \"  public static class ListFactory<E> {\",\n            \"    public List<? extends E> build() {\",\n            \"      return null;\",\n            \"    }\",\n            \"  }\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<E> {\",\n            \"    ListFactory<E> blimBuilder();\",\n            \"    Baz<E> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Property builder for blim has type foo.bar.Baz.ListFactory whose build() method \"\n                + \"returns java.util.List<? extends E> instead of java.util.List<E>\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"ListFactory<E> blimBuilder()\");\n  }\n\n  @Test\n  public void autoValueBuilderPropertyBuilderCantConstruct() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.collect.ImmutableSet;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<E> {\",\n            \"  abstract String blim();\",\n            \"\",\n            \"  public static class StringFactory {\",\n            \"    private StringFactory() {}\",\n            \"\",\n            \"    public String build() {\",\n            \"      return null;\",\n            \"    }\",\n            \"  }\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<E> {\",\n            \"    StringFactory blimBuilder();\",\n            \"    Baz<E> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Method looks like a property builder, but its type foo.bar.Baz.StringFactory \"\n                + \"does not have a public constructor and java.lang.String does not have a static \"\n                + \"builder() or newBuilder() method that returns foo.bar.Baz.StringFactory\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"StringFactory blimBuilder()\");\n  }\n\n  @Test\n  public void autoValueBuilderPropertyBuilderCantReconstruct() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<E> {\",\n            \"  abstract String blim();\",\n            \"  abstract Builder<E> toBuilder();\",\n            \"\",\n            \"  public static class StringFactory {\",\n            \"    public String build() {\",\n            \"      return null;\",\n            \"    }\",\n            \"  }\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<E> {\",\n            \"    StringFactory blimBuilder();\",\n            \"    Baz<E> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Property builder method returns foo.bar.Baz.StringFactory but there is no way to make\"\n                + \" that type from java.lang.String: java.lang.String does not have a non-static\"\n                + \" toBuilder() method that returns foo.bar.Baz.StringFactory, and\"\n                + \" foo.bar.Baz.StringFactory does not have a method addAll or putAll that accepts\"\n                + \" an argument of type java.lang.String\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"StringFactory blimBuilder()\");\n  }\n\n  @Test\n  public void autoValueBuilderPropertyBuilderWrongTypeAddAll() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.collect.ImmutableSet;\",\n            \"import java.util.Iterator;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<T> {\",\n            \"  abstract ImmutableSet<String> strings();\",\n            \"  abstract Builder<T> toBuilder();\",\n            \"\",\n            \"  public static class ImmutableSetBuilder<E> {\",\n            \"    public void addAll(Iterator<? extends E> elements) {}\",\n            \"\",\n            \"    public ImmutableSet<E> build() {\",\n            \"      return null;\",\n            \"    }\",\n            \"  }\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<T> {\",\n            \"    ImmutableSetBuilder<String> stringsBuilder();\",\n            \"    Baz<T> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Property builder method returns foo.bar.Baz.ImmutableSetBuilder<java.lang.String> but\"\n                + \" there is no way to make that type from\"\n                + \" com.google.common.collect.ImmutableSet<java.lang.String>:\"\n                + \" com.google.common.collect.ImmutableSet<java.lang.String> does not have a\"\n                + \" non-static toBuilder() method that returns\"\n                + \" foo.bar.Baz.ImmutableSetBuilder<java.lang.String>, and\"\n                + \" foo.bar.Baz.ImmutableSetBuilder<java.lang.String> does not have a method\"\n                + \" addAll or putAll that accepts an argument of type\"\n                + \" com.google.common.collect.ImmutableSet<java.lang.String>\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"ImmutableSetBuilder<String> stringsBuilder();\");\n  }\n\n  @Test\n  public void autoValueBuilderPropertyBuilderCantSet() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.collect.ImmutableSet;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<E> {\",\n            \"  abstract String blim();\",\n            \"\",\n            \"  public static class StringFactory {\",\n            \"    public String build() {\",\n            \"      return null;\",\n            \"    }\",\n            \"  }\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<E> {\",\n            \"    Builder<E> setBlim(String s);\",\n            \"    StringFactory blimBuilder();\",\n            \"    Baz<E> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Property builder method returns foo.bar.Baz.StringFactory but there is no way to make \"\n                + \"that type from java.lang.String: java.lang.String does not have a non-static \"\n                + \"toBuilder() method that returns foo.bar.Baz.StringFactory\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"StringFactory blimBuilder()\");\n  }\n\n  @Test\n  public void autoValueBuilderPropertyBuilderWrongTypeToBuilder() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.collect.ImmutableSet;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<E> {\",\n            \"  abstract Buh blim();\",\n            \"  abstract Builder<E> toBuilder();\",\n            \"\",\n            \"  public static class Buh {\",\n            \"    StringBuilder toBuilder() {\",\n            \"      return null;\",\n            \"    }\",\n            \"  }\",\n            \"\",\n            \"  public static class BuhBuilder {\",\n            \"    public Buh build() {\",\n            \"      return null;\",\n            \"    }\",\n            \"  }\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<E> {\",\n            \"    BuhBuilder blimBuilder();\",\n            \"    Baz<E> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Property builder method returns foo.bar.Baz.BuhBuilder but there is no way to make \"\n                + \"that type from foo.bar.Baz.Buh: foo.bar.Baz.Buh does not have a non-static \"\n                + \"toBuilder() method that returns foo.bar.Baz.BuhBuilder\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"BuhBuilder blimBuilder()\");\n  }\n\n  @Test\n  public void autoValueBuilderPropertyBuilderWrongElementType() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.collect.ImmutableSet;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<T, U> {\",\n            \"  abstract ImmutableSet<T> blim();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<T, U> {\",\n            \"    ImmutableSet.Builder<U> blimBuilder();\",\n            \"    Baz<T, U> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Property builder for blim has type com.google.common.collect.ImmutableSet.Builder \"\n                + \"whose build() method returns com.google.common.collect.ImmutableSet<U> \"\n                + \"instead of com.google.common.collect.ImmutableSet<T>\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"ImmutableSet.Builder<U> blimBuilder()\");\n  }\n\n  @Test\n  public void autoValueBuilderAlienMethod0() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Builder blam(String x);\",\n            \"    Builder whut();\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Method without arguments should be a build method returning foo.bar.Baz, or a getter\"\n                + \" method with the same name and type as a property method of foo.bar.Baz, or\"\n                + \" fooBuilder() where foo() or getFoo() is a property method of foo.bar.Baz\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"Builder whut()\");\n  }\n\n  @Test\n  public void autoValueBuilderAlienMethod1() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    void whut(String x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"Method whut does not correspond to a property method of foo.bar.Baz\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"void whut(String x)\");\n  }\n\n  @Test\n  public void autoValueBuilderAlienMethod2() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Builder blam(String x, String y);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"Builder methods must have 0 or 1 parameters\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"Builder blam(String x, String y)\");\n  }\n\n  @Test\n  public void autoValueBuilderMissingBuildMethod() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<T> {\",\n            \"  abstract T blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<T> {\",\n            \"    Builder<T> blam(T x);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Builder must have a single no-argument method, typically called build(), that returns\"\n                + \" foo.bar.Baz<T>\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"public interface Builder<T>\");\n  }\n\n  @Test\n  public void autoValueBuilderDuplicateBuildMethods() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Builder blam(String x);\",\n            \"    Baz build();\",\n            \"    Baz create();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Builder must have a single no-argument method, typically called build(), that returns\"\n                + \" foo.bar.Baz\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"Baz build()\");\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Builder must have a single no-argument method, typically called build(), that returns\"\n                + \" foo.bar.Baz\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"Baz create()\");\n  }\n\n  @Test\n  public void autoValueBuilderWrongTypeBuildMethod() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Builder blam(String x);\",\n            \"    String build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Method without arguments should be a build method returning foo.bar.Baz\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"String build()\");\n  }\n\n  @Test\n  public void autoValueBuilderTypeParametersDontMatch1() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<T> {\",\n            \"  abstract String blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Builder blam(String x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Type parameters of foo.bar.Baz.Builder must have same names and \"\n                + \"bounds as type parameters of foo.bar.Baz\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"public interface Builder\");\n  }\n\n  @Test\n  public void autoValueBuilderTypeParametersDontMatch2() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<T> {\",\n            \"  abstract T blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<E> {\",\n            \"    Builder<E> blam(E x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Type parameters of foo.bar.Baz.Builder must have same names and \"\n                + \"bounds as type parameters of foo.bar.Baz\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"public interface Builder<E>\");\n  }\n\n  @Test\n  public void autoValueBuilderTypeParametersDontMatch3() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz<T extends Number & Comparable<T>> {\",\n            \"  abstract T blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder<T extends Number> {\",\n            \"    Builder<T> blam(T x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"Type parameters of foo.bar.Baz.Builder must have same names and \"\n                + \"bounds as type parameters of foo.bar.Baz\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"public interface Builder<T extends Number>\");\n  }\n\n  @Test\n  public void autoValueBuilderToBuilderWrongTypeParameters() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"abstract class Baz<K extends Comparable<K>, V> {\",\n            \"  abstract K key();\",\n            \"  abstract V value();\",\n            \"  abstract Builder<V, K> toBuilder1();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  interface Builder<K extends Comparable<K>, V> {\",\n            \"    Builder<K, V> key(K key);\",\n            \"    Builder<K, V> value(V value);\",\n            \"    Baz<K, V> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"Builder converter method should return foo.bar.Baz.Builder<K, V>\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"abstract Builder<V, K> toBuilder1()\");\n  }\n\n  @Test\n  public void autoValueBuilderToBuilderDuplicate() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"abstract class Baz<K extends Comparable<K>, V> {\",\n            \"  abstract K key();\",\n            \"  abstract V value();\",\n            \"  abstract Builder<K, V> toBuilder1();\",\n            \"  abstract Builder<K, V> toBuilder2();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  interface Builder<K extends Comparable<K>, V> {\",\n            \"    Builder<K, V> key(K key);\",\n            \"    Builder<K, V> value(V value);\",\n            \"    Baz<K, V> build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"There can be at most one builder converter method\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"abstract Builder<K, V> toBuilder1()\");\n  }\n\n  @Test\n  public void getFooIsFoo() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract int getFoo();\",\n            \"  abstract boolean isFoo();\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\"More than one @AutoValue property called foo\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"getFoo\");\n    assertThat(compilation)\n        .hadErrorContaining(\"More than one @AutoValue property called foo\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"isFoo\");\n  }\n\n  @Retention(RetentionPolicy.SOURCE)\n  public @interface Foo {}\n\n  /* Processor that generates an empty class BarFoo every time it sees a class Bar annotated with\n   * @Foo.\n   */\n  public static class FooProcessor extends AbstractProcessor {\n    @Override\n    public Set<String> getSupportedAnnotationTypes() {\n      return ImmutableSet.of(Foo.class.getCanonicalName());\n    }\n\n    @Override\n    public SourceVersion getSupportedSourceVersion() {\n      return SourceVersion.latestSupported();\n    }\n\n    @Override\n    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n      Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(Foo.class);\n      for (TypeElement type : ElementFilter.typesIn(elements)) {\n        try {\n          generateFoo(type);\n        } catch (IOException e) {\n          throw new AssertionError(e);\n        }\n      }\n      return false;\n    }\n\n    private void generateFoo(TypeElement type) throws IOException {\n      String pkg = TypeSimplifier.packageNameOf(type);\n      String className = type.getSimpleName().toString();\n      String generatedClassName = className + \"Foo\";\n      JavaFileObject source =\n          processingEnv.getFiler().createSourceFile(pkg + \".\" + generatedClassName, type);\n      PrintWriter writer = new PrintWriter(source.openWriter());\n      writer.println(\"package \" + pkg + \";\");\n      writer.println(\"public class \" + generatedClassName + \" {}\");\n      writer.close();\n    }\n  }\n\n  @Test\n  public void referencingGeneratedClass() {\n    // Test that ensures that a type that does not exist can be the type of an @AutoValue property\n    // as long as it later does come into existence. The BarFoo type referenced here does not exist\n    // when the AutoValueProcessor runs on the first round, but the FooProcessor then generates it.\n    // That generation provokes a further round of annotation processing and AutoValueProcessor\n    // should succeed then.\n    JavaFileObject bazFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  public abstract BarFoo barFoo();\",\n            \"\",\n            \"  public static Baz create(BarFoo barFoo) {\",\n            \"    return new AutoValue_Baz(barFoo);\",\n            \"  }\",\n            \"}\");\n    JavaFileObject barFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Bar\",\n            \"package foo.bar;\",\n            \"\",\n            \"@\" + Foo.class.getCanonicalName(),\n            \"public abstract class Bar {\",\n            \"  public abstract BarFoo barFoo();\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new FooProcessor())\n            .withOptions(\"-Xlint:-processing\", \"-implicit:none\")\n            .compile(bazFileObject, barFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n  }\n\n  @Test\n  public void referencingGeneratedClassInAnnotation() {\n    // Test that ensures that a type that does not exist can be referenced by a copied annotation\n    // as long as it later does come into existence. The BarFoo type referenced here does not exist\n    // when the AutoValueProcessor runs on the first round, but the FooProcessor then generates it.\n    // That generation provokes a further round of annotation processing and AutoValueProcessor\n    // should succeed then.\n    // We test the three places that a class reference could appear: as the value of a Class\n    // element, as the value of a Class[] element, in a nested annotation.\n    JavaFileObject barFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Bar\",\n            \"package foo.bar;\",\n            \"\",\n            \"@\" + Foo.class.getCanonicalName(),\n            \"public abstract class Bar {\",\n            \"}\");\n    JavaFileObject referenceClassFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.ReferenceClass\",\n            \"package foo.bar;\",\n            \"\",\n            \"@interface ReferenceClass {\",\n            \"  Class<?> value() default Void.class;\",\n            \"  Class<?>[] values() default {};\",\n            \"  Nested nested() default @Nested;\",\n            \"  @interface Nested {\",\n            \"    Class<?>[] values() default {};\",\n            \"  }\",\n            \"}\");\n    ImmutableList<String> annotations =\n        ImmutableList.of(\n            \"@ReferenceClass(BarFoo.class)\",\n            \"@ReferenceClass(values = {Void.class, BarFoo.class})\",\n            \"@ReferenceClass(nested = @ReferenceClass.Nested(values = {Void.class,\"\n                + \" BarFoo.class}))\");\n    for (String annotation : annotations) {\n      JavaFileObject bazFileObject =\n          JavaFileObjects.forSourceLines(\n              \"foo.bar.Baz\",\n              \"package foo.bar;\",\n              \"\",\n              \"import com.google.auto.value.AutoValue;\",\n              \"\",\n              \"@AutoValue\",\n              \"@AutoValue.CopyAnnotations\",\n              annotation,\n              \"public abstract class Baz {\",\n              \"  public abstract int foo();\",\n              \"\",\n              \"  public static Baz create(int foo) {\",\n              \"    return new AutoValue_Baz(foo);\",\n              \"  }\",\n              \"}\");\n      Compilation compilation =\n          javac()\n              .withProcessors(new AutoValueProcessor(), new FooProcessor())\n              .withOptions(\"-Xlint:-processing\", \"-implicit:none\")\n              .compile(bazFileObject, barFileObject, referenceClassFileObject);\n      expect.about(compilations()).that(compilation).succeededWithoutWarnings();\n      if (compilation.status().equals(Compilation.Status.SUCCESS)) {\n        expect\n            .about(compilations())\n            .that(compilation)\n            .generatedSourceFile(\"foo.bar.AutoValue_Baz\")\n            .contentsAsUtf8String()\n            .contains(annotation);\n      }\n    }\n  }\n\n  @Test\n  public void annotationReferencesUndefined() {\n    // Test that we don't throw an exception if asked to compile @SuppressWarnings(UNDEFINED)\n    // where UNDEFINED is an undefined symbol.\n    JavaFileObject bazFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  @SuppressWarnings(UNDEFINED)\",\n            \"  public abstract int[] buh();\",\n            \"}\");\n    Compilation compilation1 =\n        javac()\n            .withOptions(\"-Xlint:-processing\")\n            .withProcessors(new AutoValueProcessor())\n            .compile(bazFileObject);\n    assertThat(compilation1).hadErrorCount(1);\n    assertThat(compilation1)\n        .hadErrorContaining(\"UNDEFINED\")\n        .inFile(bazFileObject)\n        .onLineContaining(\"UNDEFINED\");\n    assertThat(compilation1).hadWarningCount(1);\n    assertThat(compilation1)\n        .hadWarningContaining(\"mutable\")\n        .inFile(bazFileObject)\n        .onLineContaining(\"public abstract int[] buh()\");\n\n    // Same test, except we do successfully suppress the warning despite the UNDEFINED.\n    bazFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  @SuppressWarnings({UNDEFINED, \\\"mutable\\\"})\",\n            \"  public abstract int[] buh();\",\n            \"}\");\n    Compilation compilation2 =\n        javac()\n            .withOptions(\"-Xlint:-processing\")\n            .withProcessors(new AutoValueProcessor())\n            .compile(bazFileObject);\n    assertThat(compilation2).hadErrorCount(1);\n    assertThat(compilation2)\n        .hadErrorContaining(\"UNDEFINED\")\n        .inFile(bazFileObject)\n        .onLineContaining(\"UNDEFINED\");\n    assertThat(compilation2).hadWarningCount(0);\n  }\n\n  @Test\n  public void packagePrivateAnnotationFromOtherPackage() {\n    JavaFileObject bazFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz extends otherpackage.Parent {\",\n            \"}\");\n    JavaFileObject parentFileObject =\n        JavaFileObjects.forSourceLines(\n            \"otherpackage.Parent\",\n            \"package otherpackage;\",\n            \"\",\n            \"public abstract class Parent {\",\n            \"  @PackageAnnotation\",\n            \"  public abstract String foo();\",\n            \"\",\n            \"  @interface PackageAnnotation {}\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor())\n            .withOptions(\"-Xlint:-processing\", \"-implicit:none\")\n            .compile(bazFileObject, parentFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation).generatedSourceFile(\"foo.bar.AutoValue_Baz\");\n  }\n\n  @Test\n  public void visibleProtectedAnnotationFromOtherPackage() {\n    JavaFileObject bazFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz extends otherpackage.Parent {}\");\n    JavaFileObject parentFileObject =\n        JavaFileObjects.forSourceLines(\n            \"otherpackage.Parent\",\n            \"package otherpackage;\",\n            \"\",\n            \"public abstract class Parent {\",\n            \"  @ProtectedAnnotation\",\n            \"  public abstract String foo();\",\n            \"\",\n            \"  protected @interface ProtectedAnnotation {}\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor())\n            .withOptions(\"-Xlint:-processing\", \"-implicit:none\")\n            .compile(bazFileObject, parentFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Baz\")\n        .contentsAsUtf8String()\n        .containsMatch(\"(?s:@Parent.ProtectedAnnotation\\\\s*@Override\\\\s*public String foo\\\\(\\\\))\");\n  }\n\n  @Test\n  public void methodAnnotationsCopiedInLexicographicalOrder() {\n    JavaFileObject bazFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.package1.Annotation1;\",\n            \"import com.package2.Annotation0;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz extends Parent {\",\n            \"  @Annotation0\",\n            \"  @Annotation1\",\n            \"  @Override\",\n            \"  public abstract String foo();\",\n            \"}\");\n    JavaFileObject parentFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Parent\",\n            \"package foo.bar;\",\n            \"\",\n            \"public abstract class Parent {\",\n            \"  public abstract String foo();\",\n            \"}\");\n    JavaFileObject annotation1FileObject =\n        JavaFileObjects.forSourceLines(\n            \"com.package1.Annotation1\",\n            \"package com.package1;\",\n            \"\",\n            \"import java.lang.annotation.ElementType;\",\n            \"import java.lang.annotation.Target;\",\n            \"\",\n            \"@Target({ElementType.FIELD, ElementType.METHOD})\",\n            \"public @interface Annotation1 {}\");\n    JavaFileObject annotation0FileObject =\n        JavaFileObjects.forSourceLines(\n            \"com.package2.Annotation0\",\n            \"package com.package2;\",\n            \"\",\n            \"public @interface Annotation0 {}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor())\n            .withOptions(\"-Xlint:-processing\", \"-implicit:none\")\n            .compile(bazFileObject, parentFileObject, annotation1FileObject, annotation0FileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Baz\")\n        .contentsAsUtf8String()\n        .containsMatch(\"(?s:@Annotation1\\\\s+@Annotation0\\\\s+@Override\\\\s+public String foo\\\\(\\\\))\");\n    // @Annotation1 precedes @Annotation 0 because\n    // @com.package2.Annotation1 precedes @com.package1.Annotation0\n  }\n\n  @Test\n  public void nonVisibleProtectedAnnotationFromOtherPackage() {\n    JavaFileObject bazFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz extends otherpackage.Parent {\",\n            \"}\");\n    JavaFileObject parentFileObject =\n        JavaFileObjects.forSourceLines(\n            \"otherpackage.Parent\",\n            \"package otherpackage;\",\n            \"\",\n            \"import otherpackage.Annotations.ProtectedAnnotation;\",\n            \"\",\n            \"public abstract class Parent {\",\n            \"  @ProtectedAnnotation\",\n            \"  public abstract String foo();\",\n            \"}\");\n    JavaFileObject annotationsFileObject =\n        JavaFileObjects.forSourceLines(\n            \"otherpackage.Annotations\",\n            \"package otherpackage;\",\n            \"\",\n            \"public class Annotations {\",\n            \"  protected @interface ProtectedAnnotation {}\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor())\n            .withOptions(\"-Xlint:-processing\", \"-implicit:none\")\n            .compile(bazFileObject, parentFileObject, annotationsFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Baz\")\n        .contentsAsUtf8String()\n        .doesNotContain(\"ProtectedAnnotation\");\n  }\n\n  @Test\n  public void nonVisibleProtectedClassAnnotationFromOtherPackage() {\n    JavaFileObject bazFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Outer\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"class Outer extends otherpackage.Parent {\",\n            \"  @AutoValue\",\n            \"  @AutoValue.CopyAnnotations\",\n            \"  @ProtectedAnnotation\",\n            \"  abstract static class Inner {\",\n            \"    abstract String foo();\",\n            \"  }\",\n            \"}\");\n    JavaFileObject parentFileObject =\n        JavaFileObjects.forSourceLines(\n            \"otherpackage.Parent\",\n            \"package otherpackage;\",\n            \"\",\n            \"public abstract class Parent {\",\n            \"  protected @interface ProtectedAnnotation {}\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor())\n            .withOptions(\"-Xlint:-processing\", \"-implicit:none\")\n            .compile(bazFileObject, parentFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Outer_Inner\")\n        .contentsAsUtf8String()\n        .doesNotContain(\"ProtectedAnnotation\");\n  }\n\n  @Test\n  public void builderWithVarArgsDoesNotImportJavaUtilArrays() {\n    // Repro from https://github.com/google/auto/issues/373.\n    JavaFileObject testFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Test\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.collect.ImmutableList;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Test {\",\n            \"  abstract ImmutableList<String> foo();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  abstract static class Builder {\",\n            \"    abstract Builder foo(String... foos);\",\n            \"    abstract Test build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor())\n            .withOptions(\"-Xlint:-processing\", \"-implicit:none\")\n            .compile(testFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Test\")\n        .contentsAsUtf8String()\n        .doesNotContain(\"java.util.Arrays\");\n  }\n\n  @Test\n  public void staticBuilderMethodInBuilderClass() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"com.example.Foo\",\n            \"package com.example;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Foo {\",\n            \"  public abstract String bar();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public abstract static class Builder {\",\n            \"    public static Builder builder() {\",\n            \"      return new AutoValue_Foo.Builder();\",\n            \"    }\",\n            \"\",\n            \"    public abstract Builder setBar(String s);\",\n            \"    public abstract Foo build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor())\n            .withOptions(\"-Xlint:-processing\", \"-implicit:none\")\n            .compile(javaFileObject);\n    assertThat(compilation).succeeded();\n    assertThat(compilation)\n        .hadWarningContaining(\"Static builder() method should be in the containing class\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"builder()\");\n  }\n\n  /**\n   * Tests behaviour when the package containing an {@code @AutoValue} class also has classes with\n   * the same name as classes in {@code java.lang}. If you call a class {@code Object} you are\n   * asking for trouble, but you could innocently call a class {@code Compiler} without realizing\n   * there is a {@code java.lang.Compiler}.\n   *\n   * <p>The case where the class in question is mentioned in the {@code @AutoValue} class is the\n   * easy one, because then our logic can easily see that there is a clash and will use\n   * fully-qualified names. This is the case of the {@code Compiler} class below. The case where the\n   * class is <i>not</i> mentioned is harder. We have to realize that we can't elide the package\n   * name in {@code java.lang.Object} because there is also a {@code foo.bar.Object} in scope, and\n   * in fact it takes precedence.\n   */\n  @Test\n  public void javaLangClash() {\n    JavaFileObject object =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Object\", //\n            \"package foo.bar;\",\n            \"\",\n            \"public class Object {}\");\n    JavaFileObject string =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.String\", //\n            \"package foo.bar;\",\n            \"\",\n            \"public class String {}\");\n    JavaFileObject integer =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Integer\", //\n            \"package foo.bar;\",\n            \"\",\n            \"public class Integer {}\");\n    JavaFileObject thread =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Thread\", //\n            \"package foo.bar;\",\n            \"\",\n            \"public class Thread {}\");\n    JavaFileObject override =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Override\", //\n            \"package foo.bar;\",\n            \"\",\n            \"public class Override {}\");\n    JavaFileObject test =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Test\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Test {\",\n            \"  public abstract java.lang.Integer integer();\",\n            \"  public abstract java.lang.Thread.State state();\",\n            \"  public static Builder builder() {\",\n            \"    return new AutoValue_Test.Builder();\",\n            \"  }\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public abstract static class Builder {\",\n            \"    public abstract Builder setInteger(java.lang.Integer x);\",\n            \"    public abstract Builder setState(java.lang.Thread.State x);\",\n            \"    public abstract Test build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor())\n            .withOptions(\"-Xlint:-processing\", \"-implicit:none\")\n            .compile(object, string, integer, thread, override, test);\n    assertThat(compilation).succeededWithoutWarnings();\n  }\n\n  // This is a regression test for the problem described in\n  // https://github.com/google/auto/issues/847#issuecomment-629857642.\n  @Test\n  public void generatedParentWithGeneratedGetterButSetterInBuilder() {\n    JavaFileObject test =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Test\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import foo.baz.GeneratedParent;\",\n            \"import foo.baz.GeneratedPropertyType;\",\n            \"import java.util.Optional;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Test extends GeneratedParent {\",\n            \"  public abstract String string();\",\n            \"\",\n            \"  public static Builder builder() {\",\n            \"    return new AutoValue_Test.Builder();\",\n            \"  }\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public abstract static class Builder extends GeneratedParent.Builder<Builder> {\",\n            \"    public abstract Builder setString(String x);\",\n            \"    public abstract Builder setGenerated(GeneratedPropertyType x);\",\n            \"    public abstract Test build();\",\n            \"  }\",\n            \"}\");\n    AutoValueProcessor autoValueProcessor = new AutoValueProcessor();\n    GeneratedParentProcessor generatedParentProcessor =\n        new GeneratedParentProcessor(autoValueProcessor, expect);\n    Compilation compilation =\n        javac()\n            .withProcessors(autoValueProcessor, generatedParentProcessor)\n            .withOptions(\"-Xlint:-processing\", \"-implicit:none\")\n            .compile(test);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Test\")\n        .contentsAsUtf8String()\n        .contains(\"  public int integer() {\");\n  }\n\n  @SupportedAnnotationTypes(\"*\")\n  private static class GeneratedParentProcessor extends AbstractProcessor {\n    private static final String GENERATED_PARENT =\n        String.join(\n            \"\\n\",\n            \"package foo.baz;\",\n            \"\",\n            \"public abstract class GeneratedParent {\",\n            \"  public abstract int integer();\",\n            \"  public abstract GeneratedPropertyType generated();\",\n            \"\",\n            \"  public abstract static class Builder<B extends Builder<B>> {\",\n            \"    public abstract B setInteger(int x);\",\n            \"  }\",\n            \"}\");\n    private static final String GENERATED_PROPERTY_TYPE =\n        String.join(\n            \"\\n\", //\n            \"package foo.baz;\",\n            \"\",\n            \"public class GeneratedPropertyType {}\");\n    private static final ImmutableMap<String, String> GENERATED_TYPES =\n        ImmutableMap.of(\n            \"foo.baz.GeneratedParent\", GENERATED_PARENT,\n            \"foo.baz.GeneratedPropertyType\", GENERATED_PROPERTY_TYPE);\n\n    private final AutoValueProcessor autoValueProcessor;\n    private final Expect expect;\n\n    GeneratedParentProcessor(AutoValueProcessor autoValueProcessor, Expect expect) {\n      this.autoValueProcessor = autoValueProcessor;\n      this.expect = expect;\n    }\n\n    private boolean generated;\n\n    @Override\n    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n      if (!generated) {\n        generated = true;\n        // Check that AutoValueProcessor has already run and deferred the foo.bar.Test type because\n        // we haven't generated its parent yet.\n        expect.that(autoValueProcessor.deferredTypeNames()).contains(\"foo.bar.Test\");\n        GENERATED_TYPES.forEach(\n            (typeName, source) -> {\n              try {\n                JavaFileObject generated = processingEnv.getFiler().createSourceFile(typeName);\n                try (Writer writer = generated.openWriter()) {\n                  writer.write(source);\n                }\n              } catch (IOException e) {\n                throw new UncheckedIOException(e);\n              }\n            });\n      }\n      return false;\n    }\n\n    @Override\n    public SourceVersion getSupportedSourceVersion() {\n      return SourceVersion.latestSupported();\n    }\n  }\n\n  // This is a regression test for the problem described in\n  // https://github.com/google/auto/issues/1087.\n  @Test\n  public void kotlinMetadataAnnotationsAreImplicitlyExcludedFromCopying() {\n    JavaFileObject metadata =\n        JavaFileObjects.forSourceLines(\n            \"kotlin.Metadata\", \"package kotlin;\", \"\", \"public @interface Metadata {\", \"}\");\n    JavaFileObject test =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Test\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import kotlin.Metadata;\",\n            \"\",\n            \"@AutoValue.CopyAnnotations\",\n            \"@Metadata\",\n            \"@AutoValue\",\n            \"public abstract class Test {\",\n            \"  public abstract String string();\",\n            \"}\");\n    AutoValueProcessor autoValueProcessor = new AutoValueProcessor();\n    Compilation compilation =\n        javac()\n            .withProcessors(autoValueProcessor)\n            .withOptions(\"-Xlint:-processing\", \"-implicit:none\")\n            .compile(test, metadata);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Test\")\n        .contentsAsUtf8String()\n        .doesNotContain(\"kotlin.Metadata\");\n  }\n\n  @Test\n  public void autoValueBuilderNullableSetterPrimitiveGetter() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract int blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Builder blam(Integer x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation).succeeded();\n    assertThat(compilation)\n        .hadWarningContaining(\n            \"property method foo.bar.Baz.blam() is primitive but parameter of setter method is not\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"Builder blam(Integer x)\");\n  }\n\n  @Test\n  public void copyAnnotationsMissingExclusion() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"@AutoValue.CopyAnnotations(exclude = DoesNotExist.class)\",\n            \"public abstract class Baz {\",\n            \"  abstract int blam();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Builder blam(int x);\",\n            \"    Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation).failed();\n    assertThat(compilation)\n        .hadErrorContaining(\"DoesNotExist\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"@AutoValue.CopyAnnotations(exclude = DoesNotExist.class)\");\n  }\n\n  private static String sorted(String... imports) {\n    return stream(imports).sorted().collect(joining(\"\\n\"));\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/BuilderRequiredPropertiesTest.java",
    "content": "/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static com.google.common.collect.ImmutableSet.toImmutableSet;\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.common.truth.Truth.assertWithMessage;\n\nimport com.google.auto.value.processor.AutoValueishProcessor.Property;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Iterables;\nimport com.google.testing.compile.CompilationRule;\nimport java.util.Optional;\nimport java.util.stream.IntStream;\nimport java.util.stream.Stream;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport org.junit.Before;\nimport org.junit.ClassRule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/** Tests for {@link BuilderRequiredProperties}. */\n@RunWith(JUnit4.class)\npublic final class BuilderRequiredPropertiesTest {\n  @ClassRule public static final CompilationRule compilationRule = new CompilationRule();\n\n  private TypeMirror intType;\n  private TypeMirror stringType;\n\n  @Before\n  public void initTypes() {\n    intType = compilationRule.getTypes().getPrimitiveType(TypeKind.INT);\n    stringType = compilationRule.getElements().getTypeElement(\"java.lang.String\").asType();\n  }\n\n  @Test\n  public void fieldDeclarations() {\n    assertThat(fieldDeclarations(0)).isEmpty();\n    assertThat(fieldDeclarations(1)).containsExactly(\"private byte set$0;\");\n    assertThat(fieldDeclarations(8)).containsExactly(\"private byte set$0;\");\n    assertThat(fieldDeclarations(9)).containsExactly(\"private short set$0;\");\n    assertThat(fieldDeclarations(16)).containsExactly(\"private short set$0;\");\n    assertThat(fieldDeclarations(17)).containsExactly(\"private int set$0;\");\n    assertThat(fieldDeclarations(32)).containsExactly(\"private int set$0;\");\n    assertThat(fieldDeclarations(33)).containsExactly(\"private int set$0;\", \"private byte set$1;\");\n    assertThat(fieldDeclarations(40)).containsExactly(\"private int set$0;\", \"private byte set$1;\");\n    assertThat(fieldDeclarations(41)).containsExactly(\"private int set$0;\", \"private short set$1;\");\n    assertThat(fieldDeclarations(48)).containsExactly(\"private int set$0;\", \"private short set$1;\");\n    assertThat(fieldDeclarations(49)).containsExactly(\"private int set$0;\", \"private int set$1;\");\n    assertThat(fieldDeclarations(64)).containsExactly(\"private int set$0;\", \"private int set$1;\");\n    assertThat(fieldDeclarations(65))\n        .containsExactly(\"private int set$0;\", \"private int set$1;\", \"private byte set$2;\");\n    assertThat(fieldDeclarations(144))\n        .containsExactly(\n            \"private int set$0;\",\n            \"private int set$1;\",\n            \"private int set$2;\",\n            \"private int set$3;\",\n            \"private short set$4;\");\n  }\n\n  private ImmutableList<String> fieldDeclarations(int size) {\n    return builderRequiredProperties(size).getFieldDeclarations();\n  }\n\n  @Test\n  public void initToAllSet() {\n    assertThat(initToAllSet(0)).isEmpty();\n    assertThat(initToAllSet(1)).containsExactly(\"set$0 = (byte) 1;\");\n    assertThat(initToAllSet(8)).containsExactly(\"set$0 = (byte) 0xff;\");\n    assertThat(initToAllSet(9)).containsExactly(\"set$0 = (short) 0x1ff;\");\n    assertThat(initToAllSet(16)).containsExactly(\"set$0 = (short) 0xffff;\");\n    assertThat(initToAllSet(17)).containsExactly(\"set$0 = 0x1_ffff;\");\n    assertThat(initToAllSet(31)).containsExactly(\"set$0 = 0x7fff_ffff;\");\n    assertThat(initToAllSet(32)).containsExactly(\"set$0 = -1;\");\n    assertThat(initToAllSet(33)).containsExactly(\"set$0 = -1;\", \"set$1 = (byte) 1;\");\n    assertThat(initToAllSet(63)).containsExactly(\"set$0 = -1;\", \"set$1 = 0x7fff_ffff;\");\n    assertThat(initToAllSet(64)).containsExactly(\"set$0 = -1;\", \"set$1 = -1;\");\n    assertThat(initToAllSet(144))\n        .containsExactly(\n            \"set$0 = -1;\", \"set$1 = -1;\", \"set$2 = -1;\", \"set$3 = -1;\", \"set$4 = (short) 0xffff;\");\n  }\n\n  private ImmutableList<String> initToAllSet(int size) {\n    return builderRequiredProperties(size).getInitToAllSet();\n  }\n\n  @Test\n  public void markAsSet_reference() {\n    BuilderRequiredProperties onlyString = builderRequiredProperties(0);\n    Property stringProperty = Iterables.getOnlyElement(onlyString.getRequiredProperties());\n    assertThat(onlyString.markAsSet(stringProperty)).isEmpty();\n  }\n\n  @Test\n  public void markAsSet_byte() {\n    BuilderRequiredProperties builderRequiredProperties = builderRequiredProperties(8);\n    ImmutableList<Property> primitives = requiredPrimitiveProperties(builderRequiredProperties);\n    assertThat(primitives).hasSize(8);\n    assertThat(builderRequiredProperties.markAsSet(primitives.get(0)))\n        .isEqualTo(\"set$0 |= (byte) 1;\");\n    assertThat(builderRequiredProperties.markAsSet(primitives.get(7)))\n        .isEqualTo(\"set$0 |= (byte) 0x80;\");\n  }\n\n  @Test\n  public void markAsSet_short() {\n    BuilderRequiredProperties builderRequiredProperties = builderRequiredProperties(16);\n    ImmutableList<Property> primitives = requiredPrimitiveProperties(builderRequiredProperties);\n    assertThat(primitives).hasSize(16);\n    assertThat(builderRequiredProperties.markAsSet(primitives.get(0)))\n        .isEqualTo(\"set$0 |= (short) 1;\");\n    assertThat(builderRequiredProperties.markAsSet(primitives.get(7)))\n        .isEqualTo(\"set$0 |= (short) 0x80;\");\n    assertThat(builderRequiredProperties.markAsSet(primitives.get(15)))\n        .isEqualTo(\"set$0 |= (short) 0x8000;\");\n  }\n\n  @Test\n  public void markAsSet_int() {\n    BuilderRequiredProperties builderRequiredProperties = builderRequiredProperties(32);\n    ImmutableList<Property> primitives = requiredPrimitiveProperties(builderRequiredProperties);\n    assertThat(primitives).hasSize(32);\n    assertThat(builderRequiredProperties.markAsSet(primitives.get(0))).isEqualTo(\"set$0 |= 1;\");\n    assertThat(builderRequiredProperties.markAsSet(primitives.get(31)))\n        .isEqualTo(\"set$0 |= 0x8000_0000;\");\n  }\n\n  @Test\n  public void markAsSet_intPlusByte() {\n    BuilderRequiredProperties builderRequiredProperties = builderRequiredProperties(34);\n    ImmutableList<Property> primitives = requiredPrimitiveProperties(builderRequiredProperties);\n    assertThat(primitives).hasSize(34);\n    assertThat(builderRequiredProperties.markAsSet(primitives.get(0))).isEqualTo(\"set$0 |= 1;\");\n    assertThat(builderRequiredProperties.markAsSet(primitives.get(31)))\n        .isEqualTo(\"set$0 |= 0x8000_0000;\");\n    assertThat(builderRequiredProperties.markAsSet(primitives.get(32)))\n        .isEqualTo(\"set$1 |= (byte) 1;\");\n    assertThat(builderRequiredProperties.markAsSet(primitives.get(33)))\n        .isEqualTo(\"set$1 |= (byte) 2;\");\n  }\n\n  @Test\n  public void missingRequiredProperty_reference() {\n    BuilderRequiredProperties onlyString = builderRequiredProperties(0);\n    Property stringProperty = Iterables.getOnlyElement(onlyString.getRequiredProperties());\n    assertThat(onlyString.missingRequiredProperty(stringProperty)).isEqualTo(\"this.string == null\");\n  }\n\n  @Test\n  public void missingRequiredProperty_byte() {\n    BuilderRequiredProperties builderRequiredProperties = builderRequiredProperties(8);\n    ImmutableList<Property> primitives = requiredPrimitiveProperties(builderRequiredProperties);\n    assertThat(primitives).hasSize(8);\n    assertThat(builderRequiredProperties.missingRequiredProperty(primitives.get(0)))\n        .isEqualTo(\"(set$0 & 1) == 0\");\n    assertThat(builderRequiredProperties.missingRequiredProperty(primitives.get(7)))\n        .isEqualTo(\"(set$0 & 0x80) == 0\");\n  }\n\n  @Test\n  public void missingRequiredProperty_short() {\n    BuilderRequiredProperties builderRequiredProperties = builderRequiredProperties(16);\n    ImmutableList<Property> primitives = requiredPrimitiveProperties(builderRequiredProperties);\n    assertThat(primitives).hasSize(16);\n    assertThat(builderRequiredProperties.missingRequiredProperty(primitives.get(0)))\n        .isEqualTo(\"(set$0 & 1) == 0\");\n    assertThat(builderRequiredProperties.missingRequiredProperty(primitives.get(7)))\n        .isEqualTo(\"(set$0 & 0x80) == 0\");\n    assertThat(builderRequiredProperties.missingRequiredProperty(primitives.get(15)))\n        .isEqualTo(\"(set$0 & 0x8000) == 0\");\n  }\n\n  @Test\n  public void missingRequiredProperty_int() {\n    BuilderRequiredProperties builderRequiredProperties = builderRequiredProperties(32);\n    ImmutableList<Property> primitives = requiredPrimitiveProperties(builderRequiredProperties);\n    assertThat(primitives).hasSize(32);\n    assertThat(builderRequiredProperties.missingRequiredProperty(primitives.get(0)))\n        .isEqualTo(\"(set$0 & 1) == 0\");\n    assertThat(builderRequiredProperties.missingRequiredProperty(primitives.get(31)))\n        .isEqualTo(\"(set$0 & 0x8000_0000) == 0\");\n  }\n\n  @Test\n  public void missingRequiredProperty_intPlusByte() {\n    BuilderRequiredProperties builderRequiredProperties = builderRequiredProperties(34);\n    ImmutableList<Property> primitives = requiredPrimitiveProperties(builderRequiredProperties);\n    assertThat(primitives).hasSize(34);\n    assertThat(builderRequiredProperties.missingRequiredProperty(primitives.get(0)))\n        .isEqualTo(\"(set$0 & 1) == 0\");\n    assertThat(builderRequiredProperties.missingRequiredProperty(primitives.get(31)))\n        .isEqualTo(\"(set$0 & 0x8000_0000) == 0\");\n    assertThat(builderRequiredProperties.missingRequiredProperty(primitives.get(32)))\n        .isEqualTo(\"(set$1 & 1) == 0\");\n    assertThat(builderRequiredProperties.missingRequiredProperty(primitives.get(33)))\n        .isEqualTo(\"(set$1 & 2) == 0\");\n  }\n\n  @Test\n  public void noValueToGet_noDefaults() {\n    BuilderRequiredProperties builderRequiredProperties = builderRequiredProperties(34);\n    ImmutableList<Property> primitives = requiredPrimitiveProperties(builderRequiredProperties);\n    assertThat(primitives).hasSize(34);\n    for (Property property : primitives) {\n      assertWithMessage(\"For property %s\", property)\n          .that(builderRequiredProperties.noValueToGet(property))\n          .isEqualTo(builderRequiredProperties.missingRequiredProperty(property));\n    }\n  }\n\n  @Test\n  public void noValueToGet_withDefaults() {\n    ImmutableSet<Property> allProperties = fakePropertiesWithDefaults(0);\n    BuilderRequiredProperties builderRequiredProperties =\n        BuilderRequiredProperties.of(allProperties, /* requiredProperties= */ ImmutableSet.of());\n    ImmutableList<Property> allPropertiesList = allProperties.asList();\n    assertThat(allPropertiesList.get(0).hasDefault()).isFalse();\n    assertThat(allPropertiesList.get(1).hasDefault()).isTrue();\n    assertThat(allPropertiesList.get(2).hasDefault()).isTrue();\n    assertThat(builderRequiredProperties.noValueToGet(allPropertiesList.get(0))).isNull();\n    assertThat(builderRequiredProperties.noValueToGet(allPropertiesList.get(1)))\n        .isEqualTo(\"(set$0 & 2) == 0\");\n    assertThat(builderRequiredProperties.noValueToGet(allPropertiesList.get(2)))\n        .isEqualTo(\"(set$0 & 4) == 0\");\n  }\n\n  @Test\n  public void getAnyMissing() {\n    assertThat(builderRequiredProperties(0).getAnyMissing()).isEqualTo(\"this.string == null\");\n    assertThat(builderRequiredProperties(1).getAnyMissing())\n        .isEqualTo(\"set$0 != 1\\n|| this.string == null\");\n    assertThat(builderRequiredProperties(16).getAnyMissing())\n        .isEqualTo(\"set$0 != -1\\n|| this.string == null\");\n    assertThat(builderRequiredProperties(17).getAnyMissing())\n        .isEqualTo(\"set$0 != 0x1_ffff\\n|| this.string == null\");\n    assertThat(builderRequiredProperties(31).getAnyMissing())\n        .isEqualTo(\"set$0 != 0x7fff_ffff\\n|| this.string == null\");\n    assertThat(builderRequiredProperties(32).getAnyMissing())\n        .isEqualTo(\"set$0 != -1\\n|| this.string == null\");\n    assertThat(builderRequiredProperties(33).getAnyMissing())\n        .isEqualTo(\"set$0 != -1\\n|| set$1 != 1\\n|| this.string == null\");\n    assertThat(builderRequiredProperties(64).getAnyMissing())\n        .isEqualTo(\"set$0 != -1\\n|| set$1 != -1\\n|| this.string == null\");\n  }\n\n  @Test\n  public void getAnyMissing_withDefaults() {\n    assertThat(builderRequiredPropertiesWithDefaults(0).getAnyMissing())\n        .isEqualTo(\"(~set$0 & 1) != 0\");\n    assertThat(builderRequiredPropertiesWithDefaults(1).getAnyMissing())\n        .isEqualTo(\"(~set$0 & 3) != 0\");\n    assertThat(builderRequiredPropertiesWithDefaults(15).getAnyMissing())\n        .isEqualTo(\"(~set$0 & 0xffff) != 0\");\n    assertThat(builderRequiredPropertiesWithDefaults(16).getAnyMissing())\n        .isEqualTo(\"(~set$0 & 0x1_ffff) != 0\");\n    assertThat(builderRequiredPropertiesWithDefaults(17).getAnyMissing())\n        .isEqualTo(\"(~set$0 & 0x3_ffff) != 0\");\n\n    // TODO(emcmanus): remove the no-op `& 0xfff_ffff`\n    assertThat(builderRequiredPropertiesWithDefaults(31).getAnyMissing())\n        .isEqualTo(\"(~set$0 & 0xffff_ffff) != 0\");\n    assertThat(builderRequiredPropertiesWithDefaults(32).getAnyMissing())\n        .isEqualTo(\"(~set$0 & 0xffff_ffff) != 0\\n|| (~set$1 & 1) != 0\");\n    assertThat(builderRequiredPropertiesWithDefaults(33).getAnyMissing())\n        .isEqualTo(\"(~set$0 & 0xffff_ffff) != 0\\n|| (~set$1 & 3) != 0\");\n    assertThat(builderRequiredPropertiesWithDefaults(63).getAnyMissing())\n        .isEqualTo(\"(~set$0 & 0xffff_ffff) != 0\\n|| (~set$1 & 0xffff_ffff) != 0\");\n    assertThat(builderRequiredPropertiesWithDefaults(64).getAnyMissing())\n        .isEqualTo(\n            \"(~set$0 & 0xffff_ffff) != 0\\n|| (~set$1 & 0xffff_ffff) != 0\\n|| (~set$2 & 1) != 0\");\n  }\n\n  @Test\n  public void hex() {\n    assertThat(BuilderRequiredProperties.hex(0x0)).isEqualTo(\"0\");\n    assertThat(BuilderRequiredProperties.hex(0x1)).isEqualTo(\"1\");\n    assertThat(BuilderRequiredProperties.hex(0x9)).isEqualTo(\"9\");\n    assertThat(BuilderRequiredProperties.hex(0xa)).isEqualTo(\"0xa\");\n    assertThat(BuilderRequiredProperties.hex(0xffff)).isEqualTo(\"0xffff\");\n    assertThat(BuilderRequiredProperties.hex(0x1_0000)).isEqualTo(\"0x1_0000\");\n    assertThat(BuilderRequiredProperties.hex(0x7fff_ffff)).isEqualTo(\"0x7fff_ffff\");\n    assertThat(BuilderRequiredProperties.hex(0xffff_ffff)).isEqualTo(\"0xffff_ffff\");\n  }\n\n  private ImmutableList<Property> requiredPrimitiveProperties(\n      BuilderRequiredProperties builderRequiredProperties) {\n    return builderRequiredProperties.getRequiredProperties().stream()\n        .filter(p -> p.getTypeMirror().getKind().isPrimitive())\n        .collect(toImmutableList());\n  }\n\n  private BuilderRequiredProperties builderRequiredProperties(int primitiveCount) {\n    ImmutableSet<Property> properties = fakeProperties(primitiveCount);\n    return BuilderRequiredProperties.of(properties, properties);\n  }\n\n  private BuilderRequiredProperties builderRequiredPropertiesWithDefaults(int primitiveCount) {\n    ImmutableSet<Property> allProperties = fakePropertiesWithDefaults(primitiveCount);\n    ImmutableSet<Property> requiredProperties =\n        allProperties.stream().filter(p -> !p.hasDefault()).collect(toImmutableSet());\n    return BuilderRequiredProperties.of(allProperties, requiredProperties);\n  }\n\n  private ImmutableSet<Property> fakeProperties(int primitiveCount) {\n    return Stream.concat(\n            Stream.of(fakeProperty(\"string\", stringType, /* hasDefault= */ false)),\n            IntStream.range(0, primitiveCount)\n                .mapToObj(i -> fakeProperty(\"x\" + i, intType, /* hasDefault= */ false)))\n        .collect(toImmutableSet());\n  }\n\n  private ImmutableSet<Property> fakePropertiesWithDefaults(int primitiveCount) {\n    ImmutableSet<Property> requiredProperties = fakeProperties(primitiveCount);\n    return ImmutableSet.<Property>builder()\n        .addAll(requiredProperties)\n        .add(fakeProperty(\"stringWithDefault\", stringType, /* hasDefault= */ true))\n        .add(fakeProperty(\"intWithDefault\", intType, /* hasDefault= */ true))\n        .build();\n  }\n\n  private Property fakeProperty(String name, TypeMirror type, boolean hasDefault) {\n    return new Property(\n        /* name= */ name,\n        /* identifier= */ name,\n        /* type= */ type.toString(),\n        /* annotatedType= */ new AnnotatedTypeMirror(type),\n        /* nullableAnnotation= */ Optional.empty(),\n        /* nullables= */ Nullables.fromMethods(null, ImmutableList.of()),\n        /* getter= */ name,\n        /* maybeBuilderInitializer= */ Optional.empty(),\n        /* hasDefault= */ hasDefault);\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/ExtensionTest.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.collect.ImmutableSet.toImmutableSet;\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.testing.compile.CompilationSubject.assertThat;\nimport static com.google.testing.compile.Compiler.javac;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.value.extension.AutoValueExtension;\nimport com.google.auto.value.extension.AutoValueExtension.BuilderContext;\nimport com.google.common.base.Joiner;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Iterables;\nimport com.google.common.truth.Truth;\nimport com.google.testing.compile.Compilation;\nimport com.google.testing.compile.JavaFileObjects;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.Writer;\nimport java.net.URL;\nimport java.net.URLClassLoader;\nimport java.util.Collections;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.ServiceConfigurationError;\nimport java.util.Set;\nimport java.util.function.Consumer;\nimport java.util.jar.JarOutputStream;\nimport java.util.zip.ZipEntry;\nimport javax.annotation.processing.Filer;\nimport javax.annotation.processing.SupportedOptions;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.Modifier;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.ElementFilter;\nimport javax.lang.model.util.Elements;\nimport javax.tools.Diagnostic;\nimport javax.tools.JavaFileObject;\nimport javax.tools.StandardLocation;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic class ExtensionTest {\n\n  @Test\n  public void testExtensionCompilation() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String foo();\",\n            \"}\");\n    JavaFileObject expectedExtensionOutput =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.AutoValue_Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"final class AutoValue_Baz extends $AutoValue_Baz {\",\n            \"  public AutoValue_Baz(String foo) {\",\n            \"    super(foo);\",\n            \"  }\",\n            \"  @Override public String foo() {\",\n            \"    return \\\"foo\\\";\",\n            \"  }\",\n            \"  public String dizzle() {\\n\",\n            \"    return \\\"dizzle\\\";\\n\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(ImmutableList.of(new FooExtension())))\n            .compile(javaFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Baz\")\n        .hasSourceEquivalentTo(expectedExtensionOutput);\n  }\n\n  @Test\n  public void testExtensionConsumesProperties() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String foo();\",\n            \"  abstract String dizzle();\",\n            \"}\");\n    JavaFileObject expectedExtensionOutput =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.$AutoValue_Baz\",\n            \"package foo.bar;\",\n            \"\",\n            GeneratedImport.importGeneratedAnnotationType(),\n            \"\",\n            \"@Generated(\\\"com.google.auto.value.processor.AutoValueProcessor\\\")\",\n            \" abstract class $AutoValue_Baz extends Baz {\",\n            \"\",\n            \"  private final String foo;\",\n            \"\",\n            \"  $AutoValue_Baz(\",\n            \"      String foo) {\",\n            \"    if (foo == null) {\",\n            \"      throw new NullPointerException(\\\"Null foo\\\");\",\n            \"    }\",\n            \"    this.foo = foo;\",\n            \"  }\",\n            \"\",\n            \"  @Override\",\n            \"  String foo() {\",\n            \"    return foo;\",\n            \"  }\",\n            \"\",\n            \"  @Override\",\n            \"  public String toString() {\",\n            \"    return \\\"Baz{\\\"\",\n            \"        + \\\"foo=\\\" + foo\",\n            \"        + \\\"}\\\";\",\n            \"  }\",\n            \"\",\n            \"  @Override\",\n            \"  public boolean equals(Object o) {\",\n            \"    if (o == this) {\",\n            \"      return true;\",\n            \"    }\",\n            \"    if (o instanceof Baz) {\",\n            \"      Baz that = (Baz) o;\",\n            \"      return this.foo.equals(that.foo());\",\n            \"    }\",\n            \"    return false;\",\n            \"  }\",\n            \"\",\n            \"  @Override\",\n            \"  public int hashCode() {\",\n            \"    int h$ = 1;\",\n            \"    h$ *= 1000003;\",\n            \"    h$ ^= foo.hashCode();\",\n            \"    return h$;\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(ImmutableList.of(new FooExtension())))\n            .withOptions(\"-A\" + Nullables.NULLABLE_OPTION + \"=\")\n            .compile(javaFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.$AutoValue_Baz\")\n        .hasSourceEquivalentTo(expectedExtensionOutput);\n  }\n\n  @Test\n  public void testDoesntRaiseWarningForConsumedProperties() {\n    JavaFileObject impl =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"@AutoValue public abstract class Baz {\",\n            \"  abstract String foo();\",\n            \"  abstract String dizzle();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public abstract static class Builder {\",\n            \"    public abstract Builder foo(String s);\",\n            \"    public abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(ImmutableList.of(new FooExtension())))\n            .compile(impl);\n    assertThat(compilation).succeededWithoutWarnings();\n  }\n\n  @Test\n  public void testDoesntRaiseWarningForToBuilder() throws IOException {\n    JavaFileObject impl =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"@AutoValue public abstract class Baz {\",\n            \"  abstract String foo();\",\n            \"  abstract String dizzle();\",\n            \"  abstract Builder toBuilder();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public abstract static class Builder {\",\n            \"    public abstract Builder foo(String s);\",\n            \"    public abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(ImmutableList.of(new FooExtension())))\n            .compile(impl);\n    assertThat(compilation).succeededWithoutWarnings();\n\n    // $AutoValue_Baz is the source file generated by AutoValue itself, which is then subclassed as\n    // AutoValue_Baz by the extension. The implementation of toBuilder() should call\n    // `new AutoValue_Baz.Builder` in case the extension includes its own subclass of the Builder\n    // class.\n    Optional<JavaFileObject> generatedSourceFile =\n        compilation.generatedSourceFile(\"foo.bar.$AutoValue_Baz\");\n    assertThat(generatedSourceFile).isPresent();\n    String content =\n        generatedSourceFile.get().getCharContent(/* ignoreEncodingErrors= */ false).toString();\n    assertThat(content).doesNotContain(\"new Builder\");\n    assertThat(content).contains(\"new AutoValue_Baz.Builder\");\n  }\n\n  @Test\n  public void testCantConsumeTwice() {\n    class ConsumeDizzle extends NonFinalExtension {\n      @Override\n      public Set<String> consumeProperties(Context context) {\n        return ImmutableSet.of(\"dizzle\");\n      }\n    }\n    class AlsoConsumeDizzle extends ConsumeDizzle {}\n    AutoValueExtension ext1 = new ConsumeDizzle();\n    AutoValueExtension ext2 = new AlsoConsumeDizzle();\n    Truth.assertThat(ext1).isNotEqualTo(ext2);\n    JavaFileObject impl =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"@AutoValue public abstract class Baz {\",\n            \"  abstract String foo();\",\n            \"  abstract String dizzle();\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor(ImmutableList.of(ext1, ext2))).compile(impl);\n    assertThat(compilation)\n        .hadErrorContaining(\"wants to consume a method that was already consumed\")\n        .inFile(impl)\n        .onLineContaining(\"String dizzle()\");\n  }\n\n  @Test\n  public void testCantConsumeNonExistentProperty() {\n    class ConsumeDizzle extends NonFinalExtension {\n      @Override\n      public Set<String> consumeProperties(Context context) {\n        return ImmutableSet.of(\"dizzle\");\n      }\n    }\n    JavaFileObject impl =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"@AutoValue public abstract class Baz {\",\n            \"  abstract String foo();\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(ImmutableList.of(new ConsumeDizzle())))\n            .compile(impl);\n    assertThat(compilation)\n        .hadErrorContaining(\"wants to consume a property that does not exist: dizzle\")\n        .inFile(impl)\n        .onLineContaining(\"@AutoValue public abstract class Baz\");\n  }\n\n  @Test\n  public void testCantConsumeConcreteMethod() {\n    class ConsumeConcreteMethod extends NonFinalExtension {\n      @Override\n      public Set<ExecutableElement> consumeMethods(Context context) {\n        TypeElement autoValueClass = context.autoValueClass();\n        for (ExecutableElement method :\n            ElementFilter.methodsIn(autoValueClass.getEnclosedElements())) {\n          if (method.getSimpleName().contentEquals(\"frob\")) {\n            return ImmutableSet.of(method);\n          }\n        }\n        throw new AssertionError(\"Could not find frob method\");\n      }\n    }\n    JavaFileObject impl =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"@AutoValue public abstract class Baz {\",\n            \"  abstract String foo();\",\n            \"  void frob(int x) {}\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(ImmutableList.of(new ConsumeConcreteMethod())))\n            .compile(impl);\n    assertThat(compilation)\n        .hadErrorContainingMatch(\n            \"wants to consume a method that is not one of the abstract methods in this class\"\n                + \".*frob\\\\(int\\\\)\")\n        .inFile(impl)\n        .onLineContaining(\"@AutoValue public abstract class Baz\");\n  }\n\n  @Test\n  public void testCantConsumeNonExistentMethod() {\n    class ConsumeBogusMethod extends NonFinalExtension {\n      @Override\n      public Set<ExecutableElement> consumeMethods(Context context) {\n        // Find Integer.intValue() and try to consume that.\n        Elements elementUtils = context.processingEnvironment().getElementUtils();\n        TypeElement javaLangInteger = elementUtils.getTypeElement(Integer.class.getName());\n        for (ExecutableElement method :\n            ElementFilter.methodsIn(javaLangInteger.getEnclosedElements())) {\n          if (method.getSimpleName().contentEquals(\"intValue\")) {\n            return ImmutableSet.of(method);\n          }\n        }\n        throw new AssertionError(\"Could not find Integer.intValue()\");\n      }\n    }\n    JavaFileObject impl =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"@AutoValue public abstract class Baz {\",\n            \"  abstract String foo();\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(ImmutableList.of(new ConsumeBogusMethod())))\n            .compile(impl);\n    assertThat(compilation)\n        .hadErrorContainingMatch(\n            \"wants to consume a method that is not one of the abstract methods in this class\"\n                + \".*intValue\\\\(\\\\)\")\n        .inFile(impl)\n        .onLineContaining(\"@AutoValue public abstract class Baz\");\n  }\n\n  @Test\n  public void testExtensionWithoutConsumedPropertiesFails() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String foo();\",\n            \"  abstract String dizzle();\",\n            \"  abstract Double[] bad();\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(ImmutableList.of(new FooExtension())))\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"An @AutoValue class cannot define an array-valued property unless \"\n                + \"it is a primitive array\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"abstract Double[] bad()\");\n  }\n\n  @Test\n  public void testConsumeBuilderMethod() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String foo();\",\n            \"  @AutoValue.Builder\",\n            \"  public static abstract class Builder {\",\n            \"    abstract Builder setFoo(String value);\",\n            \"    abstract int doSomething();\",\n            \"    abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    BuilderExtension extension = new BuilderExtension();\n    extension.consumeMethod(\"doSomething\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(ImmutableList.of(extension)))\n            .compile(javaFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n  }\n\n  @Test\n  public void testAbstractBuilderMethodNotConsumedFails() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String foo();\",\n            \"  @AutoValue.Builder\",\n            \"  public static abstract class Builder {\",\n            \"    abstract Builder setFoo(String value);\",\n            \"    abstract int doSomething();\",\n            \"    abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(ImmutableList.of(new BuilderExtension())))\n            .compile(javaFileObject);\n    assertThat(compilation).hadErrorContaining(\"AutoValueBuilderNoArg\");\n  }\n\n  @Test\n  public void testConsumeMethodWithArguments() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String foo();\",\n            \"  abstract void writeToParcel(Object parcel, int flags);\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(\n                new AutoValueProcessor(ImmutableList.of(new FakeWriteToParcelExtension())))\n            .compile(javaFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n  }\n\n  @Test\n  public void testExtensionWithBuilderCompilation() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String foo();\",\n            \"  abstract String bar();\",\n            \"\",\n            \"  @AutoValue.Builder public static abstract class Builder {\",\n            \"    public abstract Builder foo(String foo);\",\n            \"    public abstract Builder bar(String bar);\",\n            \"    public abstract Baz build();\",\n            \"  }\",\n            \"}\");\n    JavaFileObject expectedExtensionOutput =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.AutoValue_Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"final class AutoValue_Baz extends $AutoValue_Baz {\",\n            \"  public AutoValue_Baz(String foo, String bar) {\",\n            \"    super(foo, bar);\",\n            \"  }\",\n            \"  @Override public String foo() {\",\n            \"    return \\\"foo\\\";\",\n            \"  }\",\n            \"  public String dizzle() {\\n\",\n            \"    return \\\"dizzle\\\";\\n\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(ImmutableList.of(new FooExtension())))\n            .compile(javaFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Baz\")\n        .hasSourceEquivalentTo(expectedExtensionOutput);\n  }\n\n  @Test\n  public void testLastExtensionGeneratesNoCode() {\n    doTestNoCode(new FooExtension(), new NonFinalExtension(), new SideFileExtension());\n  }\n\n  @Test\n  public void testFirstExtensionGeneratesNoCode() {\n    doTestNoCode(new SideFileExtension(), new FooExtension(), new NonFinalExtension());\n  }\n\n  @Test\n  public void testMiddleExtensionGeneratesNoCode() {\n    doTestNoCode(new FooExtension(), new SideFileExtension(), new NonFinalExtension());\n  }\n\n  @Test\n  public void testLoneExtensionGeneratesNoCode() {\n    doTestNoCode(new SideFileExtension());\n  }\n\n  private void doTestNoCode(AutoValueExtension... extensions) {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  public abstract String foo();\",\n            \"\",\n            \"  public static Baz create(String foo) {\",\n            \"    return new AutoValue_Baz(foo);\",\n            \"  }\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(ImmutableList.copyOf(extensions)))\n            .compile(javaFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedFile(StandardLocation.SOURCE_OUTPUT, \"foo.bar\", \"Side_Baz.java\");\n  }\n\n  @Test\n  public void testTwoExtensionsBothWantToBeFinal() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String foo();\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(\n                new AutoValueProcessor(ImmutableList.of(new FooExtension(), new FinalExtension())))\n            .compile(javaFileObject);\n    assertThat(compilation)\n        .hadErrorContaining(\n            \"More than one extension wants to generate the final class: \"\n                + FooExtension.class.getName()\n                + \", \"\n                + FinalExtension.class.getName())\n        .inFile(javaFileObject)\n        .onLineContaining(\"public abstract class Baz\");\n  }\n\n  @Test\n  public void testNonFinalThenFinal() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String foo();\",\n            \"}\");\n    FinalExtension finalExtension = new FinalExtension();\n    NonFinalExtension nonFinalExtension = new NonFinalExtension();\n    assertThat(finalExtension.generated).isFalse();\n    assertThat(nonFinalExtension.generated).isFalse();\n    Compilation compilation =\n        javac()\n            .withProcessors(\n                new AutoValueProcessor(ImmutableList.of(finalExtension, nonFinalExtension)))\n            .compile(javaFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(finalExtension.generated).isTrue();\n    assertThat(nonFinalExtension.generated).isTrue();\n  }\n\n  @Test\n  public void testFinalThenNonFinal() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String foo();\",\n            \"}\");\n    FinalExtension finalExtension = new FinalExtension();\n    NonFinalExtension nonFinalExtension = new NonFinalExtension();\n    assertThat(finalExtension.generated).isFalse();\n    assertThat(nonFinalExtension.generated).isFalse();\n    Compilation compilation =\n        javac()\n            .withProcessors(\n                new AutoValueProcessor(ImmutableList.of(nonFinalExtension, finalExtension)))\n            .compile(javaFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(finalExtension.generated).isTrue();\n    assertThat(nonFinalExtension.generated).isTrue();\n  }\n\n  @Test\n  public void testUnconsumedMethod() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  abstract String foo();\",\n            \"  abstract void writeToParcel(Object parcel, int flags);\",\n            \"}\");\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(ImmutableList.of(new FooExtension())))\n            .compile(javaFileObject);\n    assertThat(compilation).hadErrorContaining(\"writeToParcel\");\n    assertThat(compilation)\n        .hadWarningContaining(\n            \"Abstract method is neither a property getter nor a Builder converter, \"\n                + \"and no extension consumed it\")\n        .inFile(javaFileObject)\n        .onLineContaining(\"abstract void writeToParcel\");\n    // The error here comes from the Java compiler rather than AutoValue, so we don't assume\n    // much about what it looks like. On the other hand, the warning does come from AutoValue\n    // so we know what to expect.\n  }\n\n  /**\n   * Tests that the search for extensions doesn't completely blow AutoValue up if there is a corrupt\n   * jar in the {@code processorpath}. If we're not careful, that can lead to a\n   * ServiceConfigurationError.\n   */\n  @Test\n  public void testBadJarDoesntBlowUp() throws IOException {\n    File badJar = File.createTempFile(\"bogus\", \".jar\");\n    try {\n      doTestBadJarDoesntBlowUp(badJar);\n    } finally {\n      badJar.delete();\n    }\n  }\n\n  private void doTestBadJarDoesntBlowUp(File badJar) throws IOException {\n    FileOutputStream fileOutputStream = new FileOutputStream(badJar);\n    JarOutputStream jarOutputStream = new JarOutputStream(fileOutputStream);\n    byte[] bogusLine = \"bogus line\\n\".getBytes(\"UTF-8\");\n    ZipEntry zipEntry = new ZipEntry(\"META-INF/services/\" + AutoValueExtension.class.getName());\n    zipEntry.setSize(bogusLine.length);\n    jarOutputStream.putNextEntry(zipEntry);\n    jarOutputStream.write(bogusLine);\n    jarOutputStream.close();\n    ClassLoader badJarLoader = new URLClassLoader(new URL[] {badJar.toURI().toURL()});\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"}\");\n    Compilation compilation =\n        javac().withProcessors(new AutoValueProcessor(badJarLoader)).compile(javaFileObject);\n    assertThat(compilation).succeeded();\n    assertThat(compilation)\n        .hadWarningContaining(\n            \"This may be due to a corrupt jar file in the compiler's classpath.\\n  \"\n                + ServiceConfigurationError.class.getName());\n    assertThat(compilation).generatedSourceFile(\"foo.bar.AutoValue_Baz\");\n  }\n\n  private static final String CUSTOM_OPTION = \"customAnnotation.customOption\";\n\n  /**\n   * Tests that extensions providing their own (annotated) annotation types or options get picked\n   * up.\n   */\n  @Test\n  public void extensionsWithAnnotatedOptions() {\n    ExtensionWithAnnotatedOptions extension = new ExtensionWithAnnotatedOptions();\n\n    // Ensure default annotation support works\n    assertThat(extension.getSupportedOptions()).contains(CUSTOM_OPTION);\n\n    // Ensure it's carried over to the AutoValue processor\n    assertThat(new AutoValueProcessor(ImmutableList.of(extension)).getSupportedOptions())\n        .contains(CUSTOM_OPTION);\n  }\n\n  /**\n   * Tests that extensions providing their own implemented annotation types or options get picked\n   * up.\n   */\n  @Test\n  public void extensionsWithImplementedOptions() {\n    ExtensionWithImplementedOptions extension = new ExtensionWithImplementedOptions();\n\n    // Ensure it's carried over to the AutoValue processor\n    assertThat(new AutoValueProcessor(ImmutableList.of(extension)).getSupportedOptions())\n        .contains(CUSTOM_OPTION);\n  }\n\n  @SupportedOptions(CUSTOM_OPTION)\n  static class ExtensionWithAnnotatedOptions extends AutoValueExtension {\n    @Override\n    public String generateClass(\n        Context context, String className, String classToExtend, boolean isFinal) {\n      return null;\n    }\n  }\n\n  static class ExtensionWithImplementedOptions extends AutoValueExtension {\n    @Override\n    public Set<String> getSupportedOptions() {\n      return ImmutableSet.of(CUSTOM_OPTION);\n    }\n\n    @Override\n    public String generateClass(\n        Context context, String className, String classToExtend, boolean isFinal) {\n      return null;\n    }\n  }\n\n  private static class FooExtension extends AutoValueExtension {\n\n    @Override\n    public boolean applicable(Context context) {\n      return true;\n    }\n\n    @Override\n    public boolean mustBeFinal(Context context) {\n      return true;\n    }\n\n    @Override\n    public Set<String> consumeProperties(Context context) {\n      if (context.properties().containsKey(\"dizzle\")) {\n        return ImmutableSet.of(\"dizzle\");\n      } else {\n        return Collections.emptySet();\n      }\n    }\n\n    @Override\n    public String generateClass(\n        Context context, String className, String classToExtend, boolean isFinal) {\n      StringBuilder constructor =\n          new StringBuilder().append(\"  public \").append(className).append(\"(\");\n\n      boolean first = true;\n      for (Map.Entry<String, ExecutableElement> el : context.properties().entrySet()) {\n        if (first) {\n          first = false;\n        } else {\n          constructor.append(\", \");\n        }\n        constructor.append(\"String \").append(el.getKey());\n      }\n\n      constructor.append(\") {\\n\");\n      constructor.append(\"    super(\");\n\n      first = true;\n      for (Map.Entry<String, ExecutableElement> el : context.properties().entrySet()) {\n        if (first) {\n          first = false;\n        } else {\n          constructor.append(\", \");\n        }\n        constructor.append(el.getKey());\n      }\n      constructor.append(\");\\n\");\n      constructor.append(\"  }\\n\");\n\n      return String.format(\n          \"package %s;\\n\"\n              + \"\\n\"\n              + \"%s class %s extends %s {\\n\"\n              + constructor\n              + \"  @Override public String foo() {\\n\"\n              + \"    return \\\"foo\\\";\\n\"\n              + \"  }\\n\"\n              + \"  public String dizzle() {\\n\"\n              + \"    return \\\"dizzle\\\";\\n\"\n              + \"  }\\n\"\n              + \"}\",\n          context.packageName(),\n          isFinal ? \"final\" : \"abstract\",\n          className,\n          classToExtend);\n    }\n  }\n\n  private static class BuilderExtension extends AutoValueExtension {\n\n    private Optional<String> consumedMethodName;\n\n    BuilderExtension() {\n      this.consumedMethodName = Optional.empty();\n    }\n\n    public void consumeMethod(String methodName) {\n      consumedMethodName = Optional.of(methodName);\n    }\n\n    @Override\n    public boolean applicable(Context context) {\n      return true;\n    }\n\n    @Override\n    public Set<ExecutableElement> consumeBuilderMethods(Context context) {\n      return consumedMethodName\n          .map(\n              s ->\n                  context.builderAbstractMethods().stream()\n                      .filter(element -> element.getSimpleName().toString().endsWith(s))\n                      .collect(toImmutableSet()))\n          .orElseGet(ImmutableSet::of);\n    }\n\n    @Override\n    public String generateClass(\n        Context context, String className, String classToExtend, boolean isFinal) {\n      StringBuilder constructor =\n          new StringBuilder().append(\"  public \").append(className).append(\"(\");\n\n      boolean first = true;\n      for (Map.Entry<String, ExecutableElement> el : context.properties().entrySet()) {\n        if (first) {\n          first = false;\n        } else {\n          constructor.append(\", \");\n        }\n        constructor.append(\"String \").append(el.getKey());\n      }\n\n      constructor.append(\") {\\n\");\n      constructor.append(\"    super(\");\n\n      first = true;\n      for (Map.Entry<String, ExecutableElement> el : context.properties().entrySet()) {\n        if (first) {\n          first = false;\n        } else {\n          constructor.append(\", \");\n        }\n        constructor.append(el.getKey());\n      }\n      constructor.append(\");\\n\");\n      constructor.append(\"  }\\n\");\n\n      return String.format(\n          \"package %s;\\n\"\n              + \"\\n\"\n              + \"%s class %s extends %s {\\n\"\n              + constructor\n              + \"  @Override public String foo() {\\n\"\n              + \"    return \\\"foo\\\";\\n\"\n              + \"  }\\n\"\n              + \"  public static class Builder extends $AutoValue_Baz.Builder {\\n\"\n              + \"    @Override\\n\"\n              + \"    public int doSomething() {\\n\"\n              + \"      return 5;\\n\"\n              + \"    }\\n\"\n              + \"  }\\n\"\n              + \"}\",\n          context.packageName(),\n          isFinal ? \"final\" : \"abstract\",\n          className,\n          classToExtend);\n    }\n  }\n\n  // Extension that generates a class that just forwards to the parent constructor.\n  // We will make subclasses that are respectively final and non-final.\n  private abstract static class EmptyExtension extends AutoValueExtension {\n    @Override\n    public boolean applicable(Context context) {\n      return true;\n    }\n\n    @Override\n    public abstract boolean mustBeFinal(Context context);\n\n    String extraText(Context context) {\n      return \"\";\n    }\n\n    boolean generated = false;\n\n    @Override\n    public String generateClass(\n        Context context, String className, String classToExtend, boolean isFinal) {\n      generated = true;\n\n      ImmutableList.Builder<String> typesAndNamesBuilder = ImmutableList.builder();\n      context.propertyTypes().forEach((name, type) -> typesAndNamesBuilder.add(type + \" \" + name));\n      String typesAndNames = Joiner.on(\", \").join(typesAndNamesBuilder.build());\n      String template =\n          \"package {pkg};\\n\"\n              + \"\\n\"\n              + \"{finalOrAbstract} class {className} extends {classToExtend} {\\n\"\n              + \"  {className}({propertyTypesAndNames}) {\\n\"\n              + \"    super({propertyNames});\\n\"\n              + \"  }\\n\"\n              + \"  {extraText}\\n\"\n              + \"}\\n\";\n      return template\n          .replace(\"{pkg}\", context.packageName())\n          .replace(\"{finalOrAbstract}\", isFinal ? \"final\" : \"abstract\")\n          .replace(\"{className}\", className)\n          .replace(\"{classToExtend}\", classToExtend)\n          .replace(\"{propertyTypesAndNames}\", typesAndNames)\n          .replace(\"{propertyNames}\", Joiner.on(\", \").join(context.properties().keySet()))\n          .replace(\"{extraText}\", extraText(context));\n    }\n  }\n\n  private static class NonFinalExtension extends EmptyExtension {\n    @Override\n    public boolean mustBeFinal(Context context) {\n      return false;\n    }\n  }\n\n  private static class FinalExtension extends EmptyExtension {\n    @Override\n    public boolean mustBeFinal(Context context) {\n      return true;\n    }\n  }\n\n  private static class SideFileExtension extends AutoValueExtension {\n    @Override\n    public boolean applicable(Context context) {\n      return true;\n    }\n\n    @Override\n    public boolean mustBeFinal(Context context) {\n      return false;\n    }\n\n    @Override\n    public String generateClass(\n        Context context, String className, String classToExtend, boolean isFinal) {\n      String sideClassName = \"Side_\" + context.autoValueClass().getSimpleName();\n      String sideClass =\n          \"\" //\n              + \"package \"\n              + context.packageName()\n              + \";\\n\"\n              + \"class \"\n              + sideClassName\n              + \" {}\\n\";\n      Filer filer = context.processingEnvironment().getFiler();\n      try {\n        String sideClassFqName = context.packageName() + \".\" + sideClassName;\n        JavaFileObject sourceFile =\n            filer.createSourceFile(sideClassFqName, context.autoValueClass());\n        try (Writer sourceWriter = sourceFile.openWriter()) {\n          sourceWriter.write(sideClass);\n        }\n      } catch (IOException e) {\n        context\n            .processingEnvironment()\n            .getMessager()\n            .printMessage(Diagnostic.Kind.ERROR, e.toString());\n      }\n      return null;\n    }\n  }\n\n  private static class FakeWriteToParcelExtension extends NonFinalExtension {\n    private ExecutableElement writeToParcelMethod(Context context) {\n      for (ExecutableElement method : context.abstractMethods()) {\n        if (method.getSimpleName().contentEquals(\"writeToParcel\")) {\n          return method;\n        }\n      }\n      throw new AssertionError(\"Did not see abstract method writeToParcel\");\n    }\n\n    @Override\n    public Set<ExecutableElement> consumeMethods(Context context) {\n      return ImmutableSet.of(writeToParcelMethod(context));\n    }\n\n    @Override\n    String extraText(Context context) {\n      // This is perhaps overgeneral. It is simply going to generate this:\n      // @Override void writeToParcel(Object parcel, int flags) {}\n      ExecutableElement methodToImplement = writeToParcelMethod(context);\n      assertThat(methodToImplement.getReturnType().getKind()).isEqualTo(TypeKind.VOID);\n      ImmutableList.Builder<String> typesAndNamesBuilder = ImmutableList.builder();\n      for (VariableElement p : methodToImplement.getParameters()) {\n        typesAndNamesBuilder.add(p.asType() + \" \" + p.getSimpleName());\n      }\n      return \"@Override void \"\n          + methodToImplement.getSimpleName()\n          + \"(\"\n          + Joiner.on(\", \").join(typesAndNamesBuilder.build())\n          + \") {}\";\n    }\n  }\n\n  @Test\n  public void propertyTypes() {\n    JavaFileObject parent =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Parent\",\n            \"package foo.bar;\",\n            \"\",\n            \"import java.util.List;\",\n            \"\",\n            \"interface Parent<T> {\",\n            \"  T thing();\",\n            \"  List<T> list();\",\n            \"}\");\n    JavaFileObject autoValueClass =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"abstract class Baz implements Parent<String> {\",\n            \"}\");\n    ContextChecker checker =\n        context -> {\n          assertThat(context.builder()).isEmpty();\n          Map<String, TypeMirror> propertyTypes = context.propertyTypes();\n          assertThat(propertyTypes.keySet()).containsExactly(\"thing\", \"list\");\n          TypeMirror thingType = propertyTypes.get(\"thing\");\n          assertThat(thingType).isNotNull();\n          assertThat(thingType.getKind()).isEqualTo(TypeKind.DECLARED);\n          assertThat(MoreTypes.asTypeElement(thingType).getQualifiedName().toString())\n              .isEqualTo(\"java.lang.String\");\n          TypeMirror listType = propertyTypes.get(\"list\");\n          assertThat(listType).isNotNull();\n          assertThat(listType.toString()).isEqualTo(\"java.util.List<java.lang.String>\");\n        };\n    ContextCheckingExtension extension = new ContextCheckingExtension(checker);\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(ImmutableList.of(extension)))\n            .compile(autoValueClass, parent);\n    assertThat(compilation).succeededWithoutWarnings();\n  }\n\n  @Test\n  public void finalAutoValueClassName() {\n    JavaFileObject autoValueClass =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"abstract class Baz {\",\n            \"}\");\n    ContextChecker checker =\n        context -> {\n          assertThat(context.finalAutoValueClassName()).isEqualTo(\"foo.bar.AutoValue_Baz\");\n        };\n    ContextCheckingExtension extension = new ContextCheckingExtension(checker);\n    Compilation compilation =\n        javac()\n            .withProcessors(\n                new AutoValueProcessor(ImmutableList.of(extension, new FinalExtension())))\n            .compile(autoValueClass);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation).generatedSourceFile(\"foo.bar.AutoValue_Baz\");\n    // ContextCheckingExtension doesn't generate any code, so that name must be the class generated\n    // by FinalExtension.\n  }\n\n  @Test\n  public void builderContext() {\n    JavaFileObject parent =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Parent\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.common.collect.ImmutableList;\",\n            \"\",\n            \"interface Parent<T> {\",\n            \"  T thing();\",\n            \"  ImmutableList<T> list();\",\n            \"}\");\n    JavaFileObject autoValueClass =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.collect.ImmutableList;\",\n            \"\",\n            \"@AutoValue\",\n            \"abstract class Baz implements Parent<String> {\",\n            \"  static Builder builder() {\",\n            \"    return new AutoValue_Baz.Builder();\",\n            \"  }\",\n            \"\",\n            \"  abstract Builder toBuilder();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  abstract static class Builder {\",\n            \"    abstract Builder setThing(String x);\",\n            \"    abstract Builder setList(Iterable<String> x);\",\n            \"    abstract Builder setList(ImmutableList<String> x);\",\n            \"    abstract ImmutableList.Builder<String> listBuilder();\",\n            \"    abstract Baz autoBuild();\",\n            \"    Baz build() {\",\n            \"      return autoBuild();\",\n            \"    }\",\n            \"  }\",\n            \"}\");\n    ContextChecker checker =\n        context -> {\n          assertThat(context.builder()).isPresent();\n          BuilderContext builderContext = context.builder().get();\n\n          assertThat(builderContext.builderType().getQualifiedName().toString())\n              .isEqualTo(\"foo.bar.Baz.Builder\");\n\n          Set<ExecutableElement> builderMethods = builderContext.builderMethods();\n          assertThat(builderMethods).hasSize(1);\n          ExecutableElement builderMethod = Iterables.getOnlyElement(builderMethods);\n          assertThat(builderMethod.getSimpleName().toString()).isEqualTo(\"builder\");\n\n          Set<ExecutableElement> toBuilderMethods = builderContext.toBuilderMethods();\n          assertThat(toBuilderMethods).hasSize(1);\n          ExecutableElement toBuilderMethod = Iterables.getOnlyElement(toBuilderMethods);\n          assertThat(toBuilderMethod.getSimpleName().toString()).isEqualTo(\"toBuilder\");\n\n          Optional<ExecutableElement> buildMethod = builderContext.buildMethod();\n          assertThat(buildMethod).isPresent();\n          assertThat(buildMethod.get().getSimpleName().toString()).isEqualTo(\"build\");\n          assertThat(buildMethod.get().getParameters()).isEmpty();\n          assertThat(buildMethod.get().getReturnType().toString()).isEqualTo(\"foo.bar.Baz\");\n\n          ExecutableElement autoBuildMethod = builderContext.autoBuildMethod();\n          assertThat(autoBuildMethod.getSimpleName().toString()).isEqualTo(\"autoBuild\");\n          assertThat(autoBuildMethod.getModifiers()).contains(Modifier.ABSTRACT);\n          assertThat(autoBuildMethod.getParameters()).isEmpty();\n          assertThat(autoBuildMethod.getReturnType().toString()).isEqualTo(\"foo.bar.Baz\");\n\n          Map<String, Set<ExecutableElement>> setters = builderContext.setters();\n          assertThat(setters.keySet()).containsExactly(\"thing\", \"list\");\n          Set<ExecutableElement> thingSetters = setters.get(\"thing\");\n          assertThat(thingSetters).hasSize(1);\n          ExecutableElement thingSetter = Iterables.getOnlyElement(thingSetters);\n          assertThat(thingSetter.getSimpleName().toString()).isEqualTo(\"setThing\");\n          Set<ExecutableElement> listSetters = setters.get(\"list\");\n          assertThat(listSetters).hasSize(2);\n          for (ExecutableElement listSetter : listSetters) {\n            assertThat(listSetter.getSimpleName().toString()).isEqualTo(\"setList\");\n          }\n\n          Map<String, ExecutableElement> propertyBuilders = builderContext.propertyBuilders();\n          assertThat(propertyBuilders.keySet()).containsExactly(\"list\");\n          assertThat(propertyBuilders.get(\"list\").getSimpleName().toString())\n              .isEqualTo(\"listBuilder\");\n        };\n    ContextCheckingExtension extension = new ContextCheckingExtension(checker);\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(ImmutableList.of(extension)))\n            .compile(autoValueClass, parent);\n    assertThat(compilation).succeededWithoutWarnings();\n  }\n\n  @Test\n  public void builderContextWithInheritance() {\n    JavaFileObject parent =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Parent\",\n            \"package foo.bar;\",\n            \"\",\n            \"interface Parent<BuilderT> {\",\n            \"  BuilderT toBuilder();\",\n            \"  interface Builder<T, BuilderT, BuiltT> {\",\n            \"    BuilderT setThing(T x);\",\n            \"    BuiltT build();\",\n            \"  }\",\n            \"}\");\n    JavaFileObject autoValueClass =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"abstract class Baz<T> implements Parent<Baz.Builder<T>> {\",\n            \"  abstract T thing();\",\n            \"  static <T> Builder<T> builder() {\",\n            \"    return new AutoValue_Baz.Builder<>();\",\n            \"  }\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  abstract static class Builder<T> implements Parent.Builder<T, Builder<T>, Baz<T>> {\",\n            \"  }\",\n            \"}\");\n    ContextChecker checker =\n        context -> {\n          assertThat(context.builder()).isPresent();\n          BuilderContext builderContext = context.builder().get();\n\n          assertThat(builderContext.builderType().getQualifiedName().toString())\n              .isEqualTo(\"foo.bar.Baz.Builder\");\n\n          Set<ExecutableElement> builderMethods = builderContext.builderMethods();\n          assertThat(builderMethods).hasSize(1);\n          ExecutableElement builderMethod = Iterables.getOnlyElement(builderMethods);\n          assertThat(builderMethod.getSimpleName().toString()).isEqualTo(\"builder\");\n\n          Set<ExecutableElement> toBuilderMethods = builderContext.toBuilderMethods();\n          assertThat(toBuilderMethods).hasSize(1);\n          ExecutableElement toBuilderMethod = Iterables.getOnlyElement(toBuilderMethods);\n          assertThat(toBuilderMethod.getSimpleName().toString()).isEqualTo(\"toBuilder\");\n\n          Optional<ExecutableElement> buildMethod = builderContext.buildMethod();\n          assertThat(buildMethod).isPresent();\n          assertThat(buildMethod.get().getSimpleName().toString()).isEqualTo(\"build\");\n          assertThat(buildMethod.get().getParameters()).isEmpty();\n          assertThat(buildMethod.get().getReturnType().toString()).isEqualTo(\"BuiltT\");\n\n          ExecutableElement autoBuildMethod = builderContext.autoBuildMethod();\n          assertThat(autoBuildMethod).isEqualTo(buildMethod.get());\n\n          Map<String, Set<ExecutableElement>> setters = builderContext.setters();\n          assertThat(setters.keySet()).containsExactly(\"thing\");\n          Set<ExecutableElement> thingSetters = setters.get(\"thing\");\n          assertThat(thingSetters).hasSize(1);\n          ExecutableElement thingSetter = Iterables.getOnlyElement(thingSetters);\n          assertThat(thingSetter.getSimpleName().toString()).isEqualTo(\"setThing\");\n        };\n    ContextCheckingExtension extension = new ContextCheckingExtension(checker);\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(ImmutableList.of(extension)))\n            .compile(autoValueClass, parent);\n    assertThat(compilation).succeededWithoutWarnings();\n  }\n\n  @Test\n  public void oddBuilderContext() {\n    JavaFileObject autoValueClass =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import com.google.common.collect.ImmutableList;\",\n            \"\",\n            \"@AutoValue\",\n            \"abstract class Baz {\",\n            \"  abstract String string();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  abstract static class Builder {\",\n            \"    abstract Builder setString(String x);\",\n            \"    abstract Baz oddBuild();\",\n            \"    Baz build(int butNotReallyBecauseOfThisParameter) {\",\n            \"      return null;\",\n            \"    }\",\n            \"  }\",\n            \"}\");\n    ContextChecker checker =\n        context -> {\n          assertThat(context.builder()).isPresent();\n          BuilderContext builderContext = context.builder().get();\n          assertThat(builderContext.builderMethods()).isEmpty();\n          assertThat(builderContext.toBuilderMethods()).isEmpty();\n          assertThat(builderContext.buildMethod()).isEmpty();\n          assertThat(builderContext.autoBuildMethod().getSimpleName().toString())\n              .isEqualTo(\"oddBuild\");\n\n          Map<String, Set<ExecutableElement>> setters = builderContext.setters();\n          assertThat(setters.keySet()).containsExactly(\"string\");\n          Set<ExecutableElement> thingSetters = setters.get(\"string\");\n          assertThat(thingSetters).hasSize(1);\n          ExecutableElement thingSetter = Iterables.getOnlyElement(thingSetters);\n          assertThat(thingSetter.getSimpleName().toString()).isEqualTo(\"setString\");\n\n          assertThat(builderContext.propertyBuilders()).isEmpty();\n        };\n    ContextCheckingExtension extension = new ContextCheckingExtension(checker);\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(ImmutableList.of(extension)))\n            .compile(autoValueClass);\n    assertThat(compilation).succeededWithoutWarnings();\n  }\n\n  // https://github.com/google/auto/issues/809\n  @Test\n  public void propertyErrorShouldNotCrash() {\n    JavaFileObject autoValueClass =\n        JavaFileObjects.forSourceLines(\n            \"test.Test\",\n            \"package test;\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"import java.util.List;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Test {\",\n            \"  abstract Integer property();\",\n            \"  abstract List<String> listProperty();\",\n            \"\",\n            \"  @AutoValue.Builder\",\n            \"  public interface Builder {\",\n            \"    Builder property(Integer property);\",\n            \"    Builder listProperty(List<String> listProperty);\",\n            \"    Builder listProperty(Integer listPropertyValues);\",\n            \"    Test build();\",\n            \"  }\",\n            \"}\");\n    // We don't actually expect the extension to be invoked. Previously it was, and that led to a\n    // NullPointerException when calling .setters() in the checker.\n    ContextChecker checker =\n        context -> {\n          assertThat(context.builder()).isPresent();\n          assertThat(context.builder().get().setters()).isEmpty();\n        };\n    ContextCheckingExtension extension = new ContextCheckingExtension(checker);\n    Compilation compilation =\n        javac()\n            .withProcessors(new AutoValueProcessor(ImmutableList.of(extension)))\n            .compile(autoValueClass);\n    assertThat(compilation)\n        .hadErrorContaining(\"Parameter type java.lang.Integer of setter method\")\n        .inFile(autoValueClass)\n        .onLineContaining(\"Builder listProperty(Integer listPropertyValues)\");\n  }\n\n  private interface ContextChecker extends Consumer<AutoValueExtension.Context> {}\n\n  private static class ContextCheckingExtension extends AutoValueExtension {\n    private final Consumer<Context> checker;\n\n    ContextCheckingExtension(Consumer<Context> checker) {\n      this.checker = checker;\n    }\n\n    @Override\n    public boolean applicable(Context context) {\n      return true;\n    }\n\n    @Override\n    public String generateClass(\n        Context context, String className, String classToExtend, boolean isFinal) {\n      checker.accept(context);\n      return null;\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/ForwardingClassGeneratorTest.java",
    "content": "/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.auto.common.MoreTypes.asDeclared;\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static com.google.common.truth.Truth.assertThat;\nimport static java.util.Arrays.stream;\nimport static javax.lang.model.util.ElementFilter.constructorsIn;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.Iterables;\nimport com.google.testing.compile.CompilationRule;\nimport java.lang.reflect.Method;\nimport java.util.function.Supplier;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.TypeMirror;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic final class ForwardingClassGeneratorTest {\n  @Rule public final CompilationRule compilationRule = new CompilationRule();\n\n  public static class Simple implements Supplier<ImmutableList<Object>> {\n    final int anInt;\n\n    public Simple(int anInt) {\n      this.anInt = anInt;\n    }\n\n    @Override\n    public ImmutableList<Object> get() {\n      return ImmutableList.of(anInt);\n    }\n  }\n\n  @Test\n  public void simple() throws Exception {\n    testClass(Simple.class, ImmutableList.of(23));\n  }\n\n  public static class Outer {\n    public static class Inner {}\n  }\n\n  public static class KitchenSink implements Supplier<ImmutableList<Object>> {\n    final byte aByte;\n    final short aShort;\n    final int anInt;\n    final long aLong;\n    final float aFloat;\n    final double aDouble;\n    final char aChar;\n    final boolean aBoolean;\n    final String aString;\n    final ImmutableList<String> aStringList;\n    final String[] aStringArray;\n    final byte[] aByteArray;\n    final Outer.Inner anInner;\n\n    public KitchenSink(\n        byte aByte,\n        short aShort,\n        int anInt,\n        long aLong,\n        float aFloat,\n        double aDouble,\n        char aChar,\n        boolean aBoolean,\n        String aString,\n        ImmutableList<String> aStringList,\n        String[] aStringArray,\n        byte[] aByteArray,\n        Outer.Inner anInner) {\n      this.aByte = aByte;\n      this.aShort = aShort;\n      this.anInt = anInt;\n      this.aLong = aLong;\n      this.aFloat = aFloat;\n      this.aDouble = aDouble;\n      this.aChar = aChar;\n      this.aBoolean = aBoolean;\n      this.aString = aString;\n      this.aStringList = aStringList;\n      this.aStringArray = aStringArray;\n      this.aByteArray = aByteArray;\n      this.anInner = anInner;\n    }\n\n    @Override\n    public ImmutableList<Object> get() {\n      return ImmutableList.of(\n          aByte,\n          aShort,\n          anInt,\n          aLong,\n          aFloat,\n          aDouble,\n          aChar,\n          aBoolean,\n          aString,\n          aStringList,\n          aStringArray,\n          aByteArray,\n          anInner);\n    }\n  }\n\n  @Test\n  public void kitchenSink() throws Exception {\n    testClass(\n        KitchenSink.class,\n        ImmutableList.of(\n            (byte) 1,\n            (short) 2,\n            3,\n            4L,\n            5f,\n            6d,\n            '7',\n            true,\n            \"9\",\n            ImmutableList.of(\"10\"),\n            new String[] {\"11\"},\n            new byte[] {12},\n            new Outer.Inner()));\n  }\n\n  /**\n   * Tests that we can successfully generate a forwarding class that calls the constructor of the\n   * given class. We'll then load the created class and call the forwarding method, checking that it\n   * does indeed call the constructor.\n   */\n  private void testClass(\n      Class<? extends Supplier<ImmutableList<Object>>> c,\n      ImmutableList<Object> constructorParameters)\n      throws ReflectiveOperationException {\n    TypeElement typeElement = compilationRule.getElements().getTypeElement(c.getCanonicalName());\n    ExecutableElement constructorExecutable =\n        Iterables.getOnlyElement(constructorsIn(typeElement.getEnclosedElements()));\n    ImmutableList<TypeMirror> parameterTypeMirrors =\n        constructorExecutable.getParameters().stream()\n            .map(Element::asType)\n            .collect(toImmutableList());\n    String className = \"com.example.Forwarder\";\n    byte[] bytes =\n        new ForwardingClassGenerator(compilationRule.getTypes())\n            .makeConstructorForwarder(\n                className, asDeclared(typeElement.asType()), parameterTypeMirrors);\n    // Now load the class we just generated, and use reflection to call its forwarding method.\n    // That should give us an instance of the target class `c`, obtained by the call to its\n    // constructor from the forwarding method.\n    ClassLoader loader =\n        new ClassLoader() {\n          @Override\n          protected Class<?> findClass(String name) throws ClassNotFoundException {\n            if (name.equals(className)) {\n              return defineClass(className, bytes, 0, bytes.length);\n            }\n            throw new ClassNotFoundException(name);\n          }\n        };\n    Class<?> forwardingClass = Class.forName(className, true, loader);\n    Method ofMethod = stream(forwardingClass.getDeclaredMethods()).findFirst().get();\n    assertThat(ofMethod.getName()).isEqualTo(\"of\");\n    ofMethod.setAccessible(true);\n    Supplier<ImmutableList<Object>> constructed =\n        c.cast(ofMethod.invoke(null, constructorParameters.toArray()));\n    ImmutableList<Object> retrievedParameters = constructed.get();\n    assertThat(retrievedParameters).isEqualTo(constructorParameters);\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/GeneratedDoesNotExistTest.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.testing.compile.CompilationSubject.assertThat;\nimport static com.google.testing.compile.Compiler.javac;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.reflect.Reflection;\nimport com.google.errorprone.annotations.Keep;\nimport com.google.testing.compile.Compilation;\nimport com.google.testing.compile.JavaFileObjects;\nimport java.lang.reflect.InvocationHandler;\nimport java.lang.reflect.Method;\nimport java.util.Set;\nimport java.util.concurrent.ConcurrentHashMap;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.annotation.processing.Processor;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.util.Elements;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.Parameterized;\nimport org.junit.runners.Parameterized.Parameters;\n\n/**\n * Tests that {@link AutoValueProcessor} works even if run in a context where the {@code @Generated}\n * annotation does not exist.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(Parameterized.class)\npublic class GeneratedDoesNotExistTest {\n  private static final ImmutableList<String> STANDARD_OPTIONS =\n      ImmutableList.of(\"-A\" + Nullables.NULLABLE_OPTION + \"=\");\n\n  @Parameters(name = \"{0}\")\n  public static ImmutableList<Object[]> data() {\n    ImmutableList.Builder<Object[]> params = ImmutableList.builder();\n    int release = SourceVersion.latestSupported().ordinal(); // 8 for Java 8, etc.\n    if (release == 8) {\n      params.add(new Object[] {STANDARD_OPTIONS, \"javax.annotation.Generated\"});\n    } else {\n      params.add(\n          new Object[] {\n            STANDARD_OPTIONS, \"javax.annotation.processing.Generated\",\n          });\n      if (release < 20) {\n        // starting with 20 we get a warning about --release 8 going away soon\n        params.add(\n            new Object[] {\n              ImmutableList.<String>builder()\n                  .addAll(STANDARD_OPTIONS)\n                  .add(\"--release\", \"8\")\n                  .build(),\n              \"javax.annotation.Generated\",\n            });\n      }\n    }\n    return params.build();\n  }\n\n  private final ImmutableList<String> javacOptions;\n  private final String expectedAnnotation;\n\n  public GeneratedDoesNotExistTest(ImmutableList<String> javacOptions, String expectedAnnotation) {\n    this.javacOptions = javacOptions;\n    this.expectedAnnotation = expectedAnnotation;\n  }\n\n  // The classes here are basically just rigmarole to ensure that\n  // Types.getTypeElement(\"javax.annotation.Generated\") returns null, and to check that something\n  // called that. We want a Processor that forwards everything to AutoValueProcessor, except that\n  // the init(ProcessingEnvironment) method should forward a ProcessingEnvironment that filters\n  // out the Generated class. So that ProcessingEnvironment forwards everything to the real\n  // ProcessingEnvironment, except the ProcessingEnvironment.getElementUtils() method. That method\n  // returns an Elements object that forwards everything to the real Elements except\n  // getTypeElement(\"javax.annotation.Generated\") and\n  // getTypeElement(\"javax.annotation.processing.Generated\").\n\n  private static final ImmutableSet<String> GENERATED_ANNOTATIONS =\n      ImmutableSet.of(\"javax.annotation.Generated\", \"javax.annotation.processing.Generated\");\n\n  /**\n   * InvocationHandler that forwards every method to an original object, except methods where there\n   * is an implementation in this class with the same signature. So for example in the subclass\n   * {@link ElementsHandler} there is a method {@link ElementsHandler#getTypeElement(CharSequence)},\n   * which means that a call of {@link Elements#getTypeElement(CharSequence)} on the proxy with this\n   * invocation handler will end up calling that method, but a call of any of the other methods of\n   * {@code Elements} will end up calling the method on the original object.\n   */\n  private abstract static class OverridableInvocationHandler<T> implements InvocationHandler {\n    final T original;\n\n    OverridableInvocationHandler(T original) {\n      this.original = original;\n    }\n\n    @Override\n    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {\n      try {\n        Method override = getClass().getMethod(method.getName(), method.getParameterTypes());\n        if (override.getDeclaringClass() == getClass()) {\n          return override.invoke(this, args);\n        }\n      } catch (NoSuchMethodException ignored) {\n        // OK: we don't have an override for this method, so just invoke the original method.\n      }\n      return method.invoke(original, args);\n    }\n  }\n\n  private static <T> T partialProxy(Class<T> type, OverridableInvocationHandler<T> handler) {\n    return Reflection.newProxy(type, handler);\n  }\n\n  private static class ElementsHandler extends OverridableInvocationHandler<Elements> {\n\n    private final Set<String> ignoredGenerated;\n\n    ElementsHandler(Elements original, Set<String> ignoredGenerated) {\n      super(original);\n      this.ignoredGenerated = ignoredGenerated;\n    }\n\n    @Keep\n    public TypeElement getTypeElement(CharSequence name) {\n      if (GENERATED_ANNOTATIONS.contains(name.toString())) {\n        ignoredGenerated.add(name.toString());\n        return null;\n      } else {\n        return original.getTypeElement(name);\n      }\n    }\n  }\n\n  private static class ProcessingEnvironmentHandler\n      extends OverridableInvocationHandler<ProcessingEnvironment> {\n    private final Elements noGeneratedElements;\n\n    ProcessingEnvironmentHandler(ProcessingEnvironment original, Set<String> ignoredGenerated) {\n      super(original);\n      ElementsHandler elementsHandler =\n          new ElementsHandler(original.getElementUtils(), ignoredGenerated);\n      this.noGeneratedElements = partialProxy(Elements.class, elementsHandler);\n    }\n\n    @Keep\n    public Elements getElementUtils() {\n      return noGeneratedElements;\n    }\n  }\n\n  private static class ProcessorHandler extends OverridableInvocationHandler<Processor> {\n    private final Set<String> ignoredGenerated;\n\n    ProcessorHandler(Processor original, Set<String> ignoredGenerated) {\n      super(original);\n      this.ignoredGenerated = ignoredGenerated;\n    }\n\n    @Keep\n    public void init(ProcessingEnvironment processingEnv) {\n      ProcessingEnvironmentHandler processingEnvironmentHandler =\n          new ProcessingEnvironmentHandler(processingEnv, ignoredGenerated);\n      ProcessingEnvironment noGeneratedProcessingEnvironment =\n          partialProxy(ProcessingEnvironment.class, processingEnvironmentHandler);\n      original.init(noGeneratedProcessingEnvironment);\n    }\n  }\n\n  @Test\n  public void test() {\n    JavaFileObject javaFileObject =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"import com.google.auto.value.AutoValue;\",\n            \"\",\n            \"@AutoValue\",\n            \"public abstract class Baz {\",\n            \"  public static Baz create() {\",\n            \"    return new AutoValue_Baz();\",\n            \"  }\",\n            \"}\");\n    JavaFileObject expectedOutput =\n        JavaFileObjects.forSourceLines(\n            \"foo.bar.AutoValue_Baz\",\n            \"package foo.bar;\",\n            \"\",\n            \"final class AutoValue_Baz extends Baz {\",\n            \"  AutoValue_Baz() {\",\n            \"  }\",\n            \"\",\n            \"  @Override public String toString() {\",\n            \"    return \\\"Baz{\\\"\",\n            \"        + \\\"}\\\";\",\n            \"  }\",\n            \"\",\n            \"  @Override public boolean equals(Object o) {\",\n            \"    if (o == this) {\",\n            \"      return true;\",\n            \"    }\",\n            \"    if (o instanceof Baz) {\",\n            \"      return true;\",\n            \"    }\",\n            \"    return false;\",\n            \"  }\",\n            \"\",\n            \"  @Override public int hashCode() {\",\n            \"    int h$ = 1;\",\n            \"    return h$;\",\n            \"  }\",\n            \"}\");\n    Set<String> ignoredGenerated = ConcurrentHashMap.newKeySet();\n    Processor autoValueProcessor = new AutoValueProcessor();\n    ProcessorHandler handler = new ProcessorHandler(autoValueProcessor, ignoredGenerated);\n    Processor noGeneratedProcessor = partialProxy(Processor.class, handler);\n    Compilation compilation =\n        javac()\n            .withOptions(javacOptions)\n            .withProcessors(noGeneratedProcessor)\n            .compile(javaFileObject);\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Baz\")\n        .hasSourceEquivalentTo(expectedOutput);\n    assertThat(ignoredGenerated).containsExactly(expectedAnnotation);\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/GeneratedImport.java",
    "content": "/*\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport javax.lang.model.SourceVersion;\n\n/**\n * Utility methods for compile-testing tests to know which {@code @Generated} annotation is\n * available.\n */\nfinal class GeneratedImport {\n\n  /**\n   * Returns the qualified name of the {@code @Generated} annotation available during a compilation\n   * task.\n   */\n  static String generatedAnnotationType() {\n    return SourceVersion.latestSupported().compareTo(SourceVersion.RELEASE_8) > 0\n        ? \"javax.annotation.processing.Generated\"\n        : \"javax.annotation.Generated\";\n  }\n\n  /**\n   * Returns an {@code import} statement that imports the {@code @Generated} annotation {@linkplain\n   * #generatedAnnotationType() available during a compilation task}.\n   */\n  static String importGeneratedAnnotationType() {\n    return \"import \" + generatedAnnotationType() + \";\";\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/GuavaCollectionBuildersTest.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.truth.Truth.assertThat;\n\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.reflect.ClassPath;\nimport com.google.common.truth.Expect;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Modifier;\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\nimport java.util.Arrays;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * Validates the assumptions AutoValue makes about Guava immutable collection builders. We expect\n * for each public class {@code com.google.common.collect.ImmutableFoo} that:\n *\n * <ul>\n *   <li>it contains a public nested class {@code ImmutableFoo.Builder} with the same type\n *       parameters;\n *   <li>there is a public static method {@code ImmutableFoo.builder()} that returns {@code\n *       ImmutableFoo.Builder};\n *   <li>there is a method {@code ImmutableFoo.Builder.build()} that returns {@code ImmutableFoo};\n *   <li>and there is a method in {@code ImmutableFoo.Builder} called either {@code addAll} or\n *       {@code putAll} with a single parameter to which {@code ImmutableFoo} can be assigned.\n * </ul>\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class GuavaCollectionBuildersTest {\n  private static final ImmutableSet<String> NON_BUILDABLE_COLLECTIONS =\n      ImmutableSet.of(\"ImmutableCollection\");\n\n  @Rule public final Expect expect = Expect.create();\n\n  @Test\n  public void testImmutableBuilders() throws Exception {\n    ClassPath classPath = ClassPath.from(getClass().getClassLoader());\n    ImmutableSet<ClassPath.ClassInfo> classes = classPath.getAllClasses();\n    int checked = 0;\n    for (ClassPath.ClassInfo classInfo : classes) {\n      if (classInfo.getPackageName().equals(\"com.google.common.collect\")\n          && classInfo.getSimpleName().startsWith(\"Immutable\")\n          && !NON_BUILDABLE_COLLECTIONS.contains(classInfo.getSimpleName())) {\n        Class<?> c = Class.forName(classInfo.getName());\n        if (Modifier.isPublic(c.getModifiers())) {\n          checked++;\n          checkImmutableClass(c);\n        }\n      }\n    }\n    expect.that(checked).isGreaterThan(10);\n  }\n\n  private void checkImmutableClass(Class<?> c)\n      throws ClassNotFoundException, NoSuchMethodException {\n    if (!Modifier.isPublic(c.getModifiers())) {\n      return;\n    }\n\n    // We have a public static ImmutableFoo.builder()\n    Method builderMethod = c.getMethod(\"builder\");\n    assertThat(Modifier.isStatic(builderMethod.getModifiers())).isTrue();\n\n    // Its return type is Builder with the same type parameters.\n    Type builderMethodReturn = builderMethod.getGenericReturnType();\n    expect.that(builderMethodReturn).isInstanceOf(ParameterizedType.class);\n    ParameterizedType builderMethodParameterizedReturn = (ParameterizedType) builderMethodReturn;\n    Class<?> builderClass = Class.forName(c.getName() + \"$Builder\");\n    expect.that(builderMethod.getReturnType()).isEqualTo(builderClass);\n    expect\n        .withMessage(c.getName())\n        .that(Arrays.toString(builderMethodParameterizedReturn.getActualTypeArguments()))\n        .isEqualTo(Arrays.toString(builderClass.getTypeParameters()));\n\n    // The Builder has a public build() method that returns ImmutableFoo.\n    Method buildMethod = builderClass.getMethod(\"build\");\n    expect.that(buildMethod.getReturnType()).isEqualTo(c);\n\n    // The Builder has either an addAll or a putAll public method with a parameter that\n    // ImmutableFoo can be assigned to.\n    boolean found = false;\n    for (Method m : builderClass.getMethods()) {\n      if ((m.getName().equals(\"addAll\") || m.getName().equals(\"putAll\"))\n          && m.getParameterTypes().length == 1) {\n        Class<?> parameter = m.getParameterTypes()[0];\n        if (parameter.isAssignableFrom(c)) {\n          found = true;\n          break;\n        }\n      }\n    }\n    expect.withMessage(builderClass.getName() + \" has addAll or putAll\").that(found).isTrue();\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/IncrementalExtensionTest.java",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.truth.Correspondence.transforming;\nimport static com.google.common.truth.Truth.assertThat;\n\nimport com.google.auto.value.extension.AutoValueExtension;\nimport com.google.auto.value.extension.AutoValueExtension.IncrementalExtensionType;\nimport com.google.auto.value.extension.memoized.processor.MemoizeExtension;\nimport com.google.auto.value.extension.serializable.processor.SerializableAutoValueExtension;\nimport com.google.auto.value.extension.toprettystring.processor.ToPrettyStringExtension;\nimport com.google.common.collect.ImmutableList;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * Tests of Gradle incrementality in the presence of extensions. See <a\n * href=\"https://docs.gradle.org/5.0/userguide/java_plugin.html#sec:incremental_annotation_processing\">\n * incremental annotation processing</a> in the Gradle user guide.\n */\n@RunWith(JUnit4.class)\npublic class IncrementalExtensionTest {\n  @Test\n  public void builtInExtensionsAreIsolating() {\n    ImmutableList<AutoValueExtension> builtInExtensions =\n        AutoValueProcessor.extensionsFromLoader(AutoValueProcessor.class.getClassLoader());\n    // These are the current built-in extensions. We will update this test if we add more.\n    // The (Object) cast is because otherwise the inferred type is Class<?>, and we can't match\n    // that <?> with the class literals here. Even if we cast them to Class<?> it will be a\n    // different <?>.\n    assertThat(builtInExtensions)\n        .comparingElementsUsing(transforming(e -> (Object) e.getClass(), \"is class\"))\n        .containsExactly(\n            MemoizeExtension.class,\n            SerializableAutoValueExtension.class,\n            ToPrettyStringExtension.class);\n\n    AutoValueProcessor processor = new AutoValueProcessor(builtInExtensions);\n    assertThat(processor.getSupportedOptions())\n        .contains(IncrementalAnnotationProcessorType.ISOLATING.getProcessorOption());\n  }\n\n  @Test\n  public void customExtensionsAreNotIsolatingByDefault() {\n    AutoValueExtension nonIsolatingExtension = new NonIsolatingExtension();\n    assertThat(nonIsolatingExtension.incrementalType((ProcessingEnvironment) null))\n        .isEqualTo(IncrementalExtensionType.UNKNOWN);\n    ImmutableList<AutoValueExtension> extensions =\n        ImmutableList.<AutoValueExtension>builder()\n            .addAll(\n                AutoValueProcessor.extensionsFromLoader(AutoValueProcessor.class.getClassLoader()))\n            .add(nonIsolatingExtension)\n            .build();\n\n    AutoValueProcessor processor = new AutoValueProcessor(extensions);\n    assertThat(processor.getSupportedOptions())\n        .doesNotContain(IncrementalAnnotationProcessorType.ISOLATING.getProcessorOption());\n  }\n\n  @Test\n  public void customExtensionsCanBeIsolating() {\n    AutoValueExtension isolatingExtension = new IsolatingExtension();\n    assertThat(isolatingExtension.incrementalType((ProcessingEnvironment) null))\n        .isEqualTo(IncrementalExtensionType.ISOLATING);\n    ImmutableList<AutoValueExtension> extensions =\n        ImmutableList.<AutoValueExtension>builder()\n            .addAll(\n                AutoValueProcessor.extensionsFromLoader(AutoValueProcessor.class.getClassLoader()))\n            .add(isolatingExtension)\n            .build();\n\n    AutoValueProcessor processor = new AutoValueProcessor(extensions);\n    assertThat(processor.getSupportedOptions())\n        .contains(IncrementalAnnotationProcessorType.ISOLATING.getProcessorOption());\n  }\n\n  // Extensions are \"UNKNOWN\" by default.\n  private static class NonIsolatingExtension extends AutoValueExtension {\n    @Override\n    public String generateClass(\n        Context context, String className, String classToExtend, boolean isFinal) {\n      return null;\n    }\n  }\n\n  // Extensions are \"ISOLATING\" if they say they are.\n  private static class IsolatingExtension extends AutoValueExtension {\n    @Override\n    public IncrementalExtensionType incrementalType(ProcessingEnvironment processingEnvironment) {\n      return IncrementalExtensionType.ISOLATING;\n    }\n\n    @Override\n    public String generateClass(\n        Context context, String className, String classToExtend, boolean isFinal) {\n      return null;\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/JavaScannerTest.java",
    "content": "/*\n * Copyright 2015 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.truth.Truth.assertThat;\n\nimport com.google.common.base.Joiner;\nimport com.google.common.collect.ImmutableList;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class JavaScannerTest {\n  private static final ImmutableList<String> TOKENS =\n      ImmutableList.of(\n          \"  \",\n          \"\\\"hello \\\\\\\" world\\\\n\\\"\",\n          \"'a'\",\n          \"  \",\n          \"'\\\\t'\",\n          \"  \",\n          \"`com.google.Foo`\",\n          \"   \",\n          \"\\n  \",\n          \"/* comment * comment \\\" whatever\\n     comment continued */\",\n          \"  \",\n          \"t\",\n          \"h\",\n          \"i\",\n          \"n\",\n          \"g\",\n          \" \",\n          \"t\",\n          \"h\",\n          \"i\",\n          \"n\",\n          \"g\",\n          \"  \",\n          \"// line comment\",\n          \"\\n\",\n          \"/*/ tricky comment */\",\n          \"\\n\");\n\n  /**\n   * Tests basic scanner functionality. The test concatenates the tokens in {@link #TOKENS} and then\n   * retokenizes that string, checking that the same list of tokens is produced.\n   */\n  @Test\n  public void testScanner() {\n    String input = Joiner.on(\"\").join(TOKENS);\n    ImmutableList.Builder<String> tokensBuilder = ImmutableList.builder();\n    JavaScanner tokenizer = new JavaScanner(input);\n    int end;\n    for (int i = 0; i < input.length(); i = end) {\n      end = tokenizer.tokenEnd(i);\n      tokensBuilder.add(input.substring(i, end));\n    }\n    assertThat(tokensBuilder.build()).containsExactlyElementsIn(TOKENS).inOrder();\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/NullablesTest.java",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.base.StandardSystemProperty.JAVA_SPECIFICATION_VERSION;\nimport static com.google.common.collect.ImmutableList.toImmutableList;\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.common.truth.TruthJUnit.assume;\nimport static com.google.testing.compile.CompilationSubject.assertThat;\nimport static java.util.stream.Collectors.partitioningBy;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.truth.Expect;\nimport com.google.testing.compile.Compilation;\nimport com.google.testing.compile.Compiler;\nimport com.google.testing.compile.JavaFileObjects;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.annotation.processing.AbstractProcessor;\nimport javax.annotation.processing.RoundEnvironment;\nimport javax.annotation.processing.SupportedAnnotationTypes;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.util.ElementFilter;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic class NullablesTest {\n  @Rule public Expect expect = Expect.create();\n\n  @Target(ElementType.TYPE_USE)\n  @Retention(RetentionPolicy.RUNTIME)\n  public @interface Nullable {}\n\n  @Target(ElementType.TYPE_USE)\n  @Retention(RetentionPolicy.RUNTIME)\n  public @interface Irrelevant {}\n\n  // The class here has various methods that we will examine with\n  // Nullables.nullableMentionedInMethods to ensure that we do indeed detect @Nullable annotations\n  // in various contexts.\n  // This test is a lot more complicated than it should be. Ideally we would just have this Methods\n  // class be an actual class nested inside this test, and we would use CompilationRule to get\n  // the corresponding TypeElement so we could check the various methods. Unfortunately, if we\n  // do that then we get a TypeElement where all type annotations have disappeared because of\n  // https://bugs.openjdk.java.net/browse/JDK-8225377. So instead we have to use Compiler to compile\n  // the code here with a special annotation processor that will check the annotations of the\n  // just-compiled class. Since the processor is running as part of the same compilation, we don't\n  // lose the type annotations.\n\n  private static final ImmutableList<String> METHOD_LINES =\n      ImmutableList.of(\n          // Methods in this class whose names begin with \"no\" do not mention @Nullable anywhere.\",\n          // All other methods do.\",\n          \"package foo.bar;\",\n          \"\",\n          \"import \" + Irrelevant.class.getCanonicalName() + \";\",\n          \"import \" + Nullable.class.getCanonicalName() + \";\",\n          \"import java.util.List;\",\n          \"\",\n          \"abstract class Methods {\",\n          \"  void noAnnotations() {}\",\n          \"  abstract int noAnnotationsEither(int x);\",\n          \"  abstract @Irrelevant String noRelevantAnnotations(@Irrelevant int x);\",\n          \"  abstract @Nullable String nullableString();\",\n          \"  abstract String @Nullable [] nullableArrayOfString();\",\n          \"  abstract @Nullable String[] arrayOfNullableString();\",\n          \"  abstract @Nullable String @Nullable [] nullableArrayOfNullableString();\",\n          \"  abstract List<@Nullable String> listOfNullableString();\",\n          \"  abstract List<? extends @Nullable Object> listOfExtendsNullable();\",\n          \"  abstract List<? super @Nullable Number> listOfSuperNullable();\",\n          \"  abstract <T extends @Nullable Object> T nullableTypeParamBound();\",\n          \"  abstract <T> @Nullable T nullableTypeParamRef();\",\n          \"  void nullableParam(@Nullable String x) {}\",\n          \"  void nullableParamBound(List<? extends @Nullable String> x) {}\",\n          \"}\");\n\n  @Test\n  public void nullableMentionedInMethods() {\n    // Sadly we can't rely on JDK 8 to handle type annotations correctly.\n    // Some versions do, some don't. So skip the test unless we are on at least JDK 9.\n    double javaVersion = Double.parseDouble(JAVA_SPECIFICATION_VERSION.value());\n    assume().that(javaVersion).isAtLeast(9.0);\n    NullableProcessor processor = new NullableProcessor(expect);\n    Compilation compilation =\n        Compiler.javac()\n            .withProcessors(processor)\n            .compile(JavaFileObjects.forSourceLines(\"foo.bar.Methods\", METHOD_LINES));\n    assertThat(compilation).succeededWithoutWarnings();\n    assertThat(processor.ran).isTrue();\n    // If any `expect` calls failed then the test will fail now because of the Expect rule.\n  }\n\n  @SupportedAnnotationTypes(\"*\")\n  private static class NullableProcessor extends AbstractProcessor {\n\n    private final Expect expect;\n    boolean ran;\n\n    NullableProcessor(Expect expect) {\n      this.expect = expect;\n    }\n\n    @Override\n    public SourceVersion getSupportedSourceVersion() {\n      return SourceVersion.latestSupported();\n    }\n\n    @Override\n    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n      if (roundEnv.processingOver()) {\n        TypeElement methodsElement =\n            processingEnv.getElementUtils().getTypeElement(\"foo.bar.Methods\");\n        expect.that(methodsElement).isNotNull();\n\n        List<ExecutableElement> methods =\n            ElementFilter.methodsIn(methodsElement.getEnclosedElements());\n        Map<Boolean, List<ExecutableElement>> partitionedMethods =\n            methods.stream()\n                .collect(partitioningBy(p -> !p.getSimpleName().toString().startsWith(\"no\")));\n        List<ExecutableElement> nullableMethods = partitionedMethods.get(true);\n        List<ExecutableElement> notNullableMethods = partitionedMethods.get(false);\n\n        expect\n            .that(Nullables.fromMethods(null, notNullableMethods).nullableTypeAnnotations())\n            .isEmpty();\n\n        TypeElement nullableElement =\n            processingEnv.getElementUtils().getTypeElement(Nullable.class.getCanonicalName());\n        expect.that(nullableElement).isNotNull();\n        DeclaredType nullableType = MoreTypes.asDeclared(nullableElement.asType());\n\n        for (ExecutableElement nullableMethod : nullableMethods) {\n          // Make a list with all the methods that don't have @Nullable plus one method that does.\n          ImmutableList<ExecutableElement> notNullablePlusNullable =\n              ImmutableList.<ExecutableElement>builder()\n                  .addAll(notNullableMethods)\n                  .add(nullableMethod)\n                  .build();\n          expect\n              .withMessage(\"method %s should have @Nullable\", nullableMethod)\n              .that(\n                  Nullables.fromMethods(null, notNullablePlusNullable)\n                      .nullableTypeAnnotations()\n                      .stream()\n                      .map(AnnotationMirror::getAnnotationType)\n                      .collect(toImmutableList()))\n              .containsExactly(nullableType);\n        }\n        ran = true;\n      }\n      return false;\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/PropertyAnnotationsTest.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.testing.compile.CompilationSubject.assertThat;\nimport static com.google.testing.compile.Compiler.javac;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.ImmutableSortedSet;\nimport com.google.testing.compile.Compilation;\nimport com.google.testing.compile.JavaFileObjects;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Inherited;\nimport java.lang.annotation.Target;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.annotation.Nullable;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * Tests to ensure annotations are kept on AutoValue generated classes\n *\n * @author jmcampanini\n */\n@RunWith(JUnit4.class)\npublic class PropertyAnnotationsTest {\n  private static final String TEST_ANNOTATION = \"@PropertyAnnotationsTest.TestAnnotation\";\n  private static final String TEST_ARRAY_ANNOTATION =\n      \"@PropertyAnnotationsTest.TestArrayAnnotation\";\n\n  public enum TestEnum {\n    A,\n    B;\n\n    @Override\n    public String toString() {\n      // used to prove that the method we determine the value does not use the `toString()` method\n      // of the enum\n      return \"not the same value\";\n    }\n  }\n\n  public @interface TestAnnotation {\n    byte testByte() default 1;\n\n    short testShort() default 2;\n\n    int testInt() default 3;\n\n    long testLong() default 4L;\n\n    float testFloat() default 5.6f;\n\n    double testDouble() default 7.8d;\n\n    char testChar() default 'a';\n\n    String testString() default \"10\";\n\n    boolean testBoolean() default false;\n\n    Class<?> testClass() default TestEnum.class;\n\n    TestEnum testEnum() default TestEnum.A;\n\n    OtherAnnotation testAnnotation() default @OtherAnnotation(foo = 23, bar = \"baz\");\n  }\n\n  public @interface OtherAnnotation {\n    int foo() default 123;\n\n    String bar() default \"bar\";\n  }\n\n  public @interface TestArrayAnnotation {\n    byte[] testBytes() default {1, 2};\n\n    short[] testShorts() default {3, 4};\n\n    int[] testInts() default {5, 6};\n\n    long[] testLongs() default {7L, 8L};\n\n    float[] testFloats() default {9.1f, 2.3f};\n\n    double[] testDoubles() default {4.5d, 6.7d};\n\n    char[] testChars() default {'a', 'b'};\n\n    String[] testStrings() default {\"cde\", \"fgh\"};\n\n    boolean[] testBooleans() default {true, false};\n\n    Class<?>[] testClasses() default {TestEnum.class, TestEnum.class};\n\n    TestEnum[] testEnums() default {TestEnum.A, TestEnum.B};\n\n    OtherAnnotation[] testAnnotations() default {\n      @OtherAnnotation(foo = 999), @OtherAnnotation(bar = \"baz\")\n    };\n  }\n\n  @Inherited\n  public @interface InheritedAnnotation {}\n\n  private static class InputFileBuilder {\n    Iterable<String> imports = ImmutableList.of();\n    List<String> annotations = new ArrayList<>();\n    List<String> innerTypes = new ArrayList<>();\n\n    InputFileBuilder setImports(Iterable<String> imports) {\n      this.imports = imports;\n      return this;\n    }\n\n    InputFileBuilder addAnnotations(String... annotations) {\n      this.annotations.addAll(ImmutableList.copyOf(annotations));\n      return this;\n    }\n\n    InputFileBuilder addAnnotations(Iterable<String> annotations) {\n      this.annotations.addAll(ImmutableList.copyOf(annotations));\n      return this;\n    }\n\n    InputFileBuilder addInnerTypes(String... innerTypes) {\n      this.innerTypes.addAll(ImmutableList.copyOf(innerTypes));\n      return this;\n    }\n\n    JavaFileObject build() {\n      ImmutableList<String> list =\n          ImmutableList.<String>builder()\n              .add(\"package foo.bar;\", \"\", \"import com.google.auto.value.AutoValue;\")\n              .addAll(imports)\n              .add(\"\", \"@AutoValue\", \"public abstract class Baz {\")\n              .addAll(annotations)\n              .add(\n                  \"  public abstract int buh();\",\n                  \"\",\n                  \"  public static Baz create(int buh) {\",\n                  \"    return new AutoValue_Baz(buh);\",\n                  \"  }\")\n              .addAll(innerTypes)\n              .add(\"}\")\n              .build();\n      String[] lines = list.toArray(new String[list.size()]);\n      return JavaFileObjects.forSourceLines(\"foo.bar.Baz\", lines);\n    }\n  }\n\n  private static class OutputFileBuilder {\n    Iterable<String> imports = ImmutableList.of();\n    List<String> fieldAnnotations = new ArrayList<>();\n    List<String> methodAnnotations = new ArrayList<>();\n\n    OutputFileBuilder setImports(Iterable<String> imports) {\n      this.imports = imports;\n      return this;\n    }\n\n    OutputFileBuilder addFieldAnnotations(String... annotations) {\n      this.fieldAnnotations.addAll(ImmutableList.copyOf(annotations));\n      return this;\n    }\n\n    OutputFileBuilder addMethodAnnotations(String... innerTypes) {\n      this.methodAnnotations.addAll(ImmutableList.copyOf(innerTypes));\n      return this;\n    }\n\n    OutputFileBuilder addMethodAnnotations(Iterable<String> innerTypes) {\n      this.methodAnnotations.addAll(ImmutableList.copyOf(innerTypes));\n      return this;\n    }\n\n    JavaFileObject build() {\n      String nullable = methodAnnotations.contains(\"@Nullable\") ? \"@Nullable \" : \"\";\n      ImmutableSortedSet<String> allImports =\n          ImmutableSortedSet.<String>naturalOrder()\n              .add(GeneratedImport.importGeneratedAnnotationType())\n              .addAll(imports)\n              .build();\n      ImmutableList<String> list =\n          ImmutableList.<String>builder()\n              .add(\"package foo.bar;\", \"\")\n              .addAll(allImports)\n              .add(\n                  \"\",\n                  \"@Generated(\\\"\" + AutoValueProcessor.class.getName() + \"\\\")\",\n                  \"final class AutoValue_Baz extends Baz {\")\n              .addAll(fieldAnnotations)\n              .add(\n                  \"  private final int buh;\",\n                  \"  AutoValue_Baz(\" + nullable + \"int buh) {\",\n                  \"    this.buh = buh;\",\n                  \"  }\",\n                  \"\")\n              .addAll(methodAnnotations)\n              .add(\n                  \"  @Override public int buh() {\",\n                  \"    return buh;\",\n                  \"  }\",\n                  \"\",\n                  \"  @Override public String toString() {\",\n                  \"    return \\\"Baz{\\\"\",\n                  \"        + \\\"buh=\\\" + buh\",\n                  \"        + \\\"}\\\";\",\n                  \"  }\",\n                  \"\",\n                  \"  @Override public boolean equals(Object o) {\",\n                  \"    if (o == this) {\",\n                  \"      return true;\",\n                  \"    }\",\n                  \"    if (o instanceof Baz) {\",\n                  \"      Baz that = (Baz) o;\",\n                  \"      return this.buh == that.buh();\",\n                  \"    }\",\n                  \"    return false;\",\n                  \"  }\",\n                  \"\",\n                  \"  @Override public int hashCode() {\",\n                  \"    int h$ = 1;\",\n                  \"    h$ *= 1000003;\",\n                  \"    h$ ^= buh;\",\n                  \"    return h$;\",\n                  \"  }\",\n                  \"}\")\n              .build();\n\n      String[] lines = list.toArray(new String[list.size()]);\n      return JavaFileObjects.forSourceLines(\"foo.bar.AutoValue_Baz\", lines);\n    }\n  }\n\n  private ImmutableSet<String> getImports(Class<?>... classes) {\n    ImmutableSet.Builder<String> stringBuilder = ImmutableSortedSet.naturalOrder();\n    for (Class<?> clazz : classes) {\n      stringBuilder.add(\"import \" + clazz.getName() + \";\");\n    }\n    return stringBuilder.build();\n  }\n\n  private void assertGeneratedMatches(\n      Iterable<String> imports,\n      Iterable<String> annotations,\n      Iterable<String> expectedMethodAnnotations) {\n\n    JavaFileObject javaFileObject =\n        new InputFileBuilder().setImports(imports).addAnnotations(annotations).build();\n\n    JavaFileObject expectedOutput =\n        new OutputFileBuilder()\n            .setImports(imports)\n            .addMethodAnnotations(expectedMethodAnnotations)\n            .build();\n\n    Compilation compilation =\n        javac()\n            .withOptions(\"-A\" + Nullables.NULLABLE_OPTION + \"=\")\n            .withProcessors(new AutoValueProcessor())\n            .compile(javaFileObject);\n    assertThat(compilation).succeeded();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Baz\")\n        .hasSourceEquivalentTo(expectedOutput);\n  }\n\n  @Test\n  public void testSimpleAnnotation() {\n    assertGeneratedMatches(\n        ImmutableList.of(), ImmutableList.of(\"@Deprecated\"), ImmutableList.of(\"@Deprecated\"));\n  }\n\n  @Test\n  public void testSingleStringValueAnnotation() {\n    assertGeneratedMatches(\n        ImmutableList.of(),\n        ImmutableList.of(\"@SuppressWarnings(\\\"a\\\")\"),\n        ImmutableList.of(\"@SuppressWarnings(\\\"a\\\")\"));\n  }\n\n  @Test\n  public void testMultiStringValueAnnotation() {\n    assertGeneratedMatches(\n        ImmutableList.of(),\n        ImmutableList.of(\"@SuppressWarnings({\\\"a\\\", \\\"b\\\"})\"),\n        ImmutableList.of(\"@SuppressWarnings({\\\"a\\\", \\\"b\\\"})\"));\n  }\n\n  @Test\n  public void testNumberValueAnnotation() {\n    assertGeneratedMatches(\n        getImports(PropertyAnnotationsTest.class),\n        ImmutableList.of(TEST_ANNOTATION + \"(testShort = 1, testInt = 2, testLong = 3L)\"),\n        ImmutableList.of(TEST_ANNOTATION + \"(testShort = 1, testInt = 2, testLong = 3L)\"));\n  }\n\n  @Test\n  public void testByteValueAnnotation() {\n    assertGeneratedMatches(\n        getImports(PropertyAnnotationsTest.class),\n        ImmutableList.of(TEST_ANNOTATION + \"(testByte = 0)\"),\n        ImmutableList.of(TEST_ANNOTATION + \"(testByte = 0)\"));\n  }\n\n  @Test\n  public void testDecimalValueAnnotation() {\n    assertGeneratedMatches(\n        getImports(PropertyAnnotationsTest.class),\n        ImmutableList.of(TEST_ANNOTATION + \"(testDouble = 1.2d, testFloat = 3.4f)\"),\n        ImmutableList.of(TEST_ANNOTATION + \"(testDouble = 1.2d, testFloat = 3.4f)\"));\n  }\n\n  @Test\n  public void testOtherValuesAnnotation() {\n    assertGeneratedMatches(\n        getImports(PropertyAnnotationsTest.class),\n        ImmutableList.of(\n            TEST_ANNOTATION + \"(testBoolean = true, testString = \\\"hallo\\\", testChar = 'a')\"),\n        ImmutableList.of(\n            TEST_ANNOTATION + \"(testBoolean = true, testString = \\\"hallo\\\", testChar = 'a')\"));\n  }\n\n  @Test\n  public void testClassAnnotation() {\n    assertGeneratedMatches(\n        getImports(PropertyAnnotationsTest.class),\n        ImmutableList.of(TEST_ANNOTATION + \"(testClass = String.class)\"),\n        ImmutableList.of(TEST_ANNOTATION + \"(testClass = String.class)\"));\n  }\n\n  @Test\n  public void testEnumAnnotation() {\n    assertGeneratedMatches(\n        getImports(PropertyAnnotationsTest.class),\n        ImmutableList.of(\n            TEST_ANNOTATION\n                + \"(testEnum = \"\n                + PropertyAnnotationsTest.class.getName()\n                + \".TestEnum.A)\"),\n        ImmutableList.of(TEST_ANNOTATION + \"(testEnum = PropertyAnnotationsTest.TestEnum.A)\"));\n  }\n\n  @Test\n  public void testEmptyAnnotationAnnotation() {\n    assertGeneratedMatches(\n        getImports(PropertyAnnotationsTest.class),\n        ImmutableList.of(\n            TEST_ANNOTATION + \"(testAnnotation = @PropertyAnnotationsTest.OtherAnnotation)\"),\n        ImmutableList.of(\n            TEST_ANNOTATION + \"(testAnnotation = @PropertyAnnotationsTest.OtherAnnotation)\"));\n  }\n\n  @Test\n  public void testValuedAnnotationAnnotation() {\n    assertGeneratedMatches(\n        getImports(PropertyAnnotationsTest.class),\n        ImmutableList.of(\n            TEST_ANNOTATION\n                + \"(testAnnotation = @PropertyAnnotationsTest.OtherAnnotation(foo=999))\"),\n        ImmutableList.of(\n            TEST_ANNOTATION\n                + \"(testAnnotation = @PropertyAnnotationsTest.OtherAnnotation(foo=999))\"));\n  }\n\n  @Test\n  public void testNumberArrayAnnotation() {\n    assertGeneratedMatches(\n        getImports(PropertyAnnotationsTest.class),\n        ImmutableList.of(\n            TEST_ARRAY_ANNOTATION\n                + \"(testShorts = {2, 3}, testInts = {4, 5}, testLongs = {6L, 7L})\"),\n        ImmutableList.of(\n            TEST_ARRAY_ANNOTATION\n                + \"(testShorts = {2, 3}, testInts = {4, 5}, testLongs = {6L, 7L})\"));\n  }\n\n  @Test\n  public void testByteArrayAnnotation() {\n    assertGeneratedMatches(\n        getImports(PropertyAnnotationsTest.class),\n        ImmutableList.of(TEST_ARRAY_ANNOTATION + \"(testBytes = {0, 1})\"),\n        ImmutableList.of(TEST_ARRAY_ANNOTATION + \"(testBytes = {0, 1})\"));\n  }\n\n  @Test\n  public void testDecimalArrayAnnotation() {\n    assertGeneratedMatches(\n        getImports(PropertyAnnotationsTest.class),\n        ImmutableList.of(\n            TEST_ARRAY_ANNOTATION + \"(testDoubles = {1.2d, 3.4d}, testFloats = {5.6f, 7.8f})\"),\n        ImmutableList.of(\n            TEST_ARRAY_ANNOTATION + \"(testDoubles = {1.2d, 3.4d}, testFloats = {5.6f, 7.8f})\"));\n  }\n\n  @Test\n  public void testOtherArrayAnnotation() {\n    assertGeneratedMatches(\n        getImports(PropertyAnnotationsTest.class),\n        ImmutableList.of(\n            TEST_ARRAY_ANNOTATION\n                + \"(testBooleans = {false, false},\"\n                + \" testStrings = {\\\"aaa\\\", \\\"bbb\\\"}, testChars={'x', 'y'})\"),\n        ImmutableList.of(\n            TEST_ARRAY_ANNOTATION\n                + \"(testBooleans = {false, false},\"\n                + \" testStrings = {\\\"aaa\\\", \\\"bbb\\\"}, testChars={'x', 'y'})\"));\n  }\n\n  @Test\n  public void testClassArrayAnnotation() {\n    assertGeneratedMatches(\n        getImports(PropertyAnnotationsTest.class),\n        ImmutableList.of(TEST_ARRAY_ANNOTATION + \"(testClasses = {String.class, Long.class})\"),\n        ImmutableList.of(TEST_ARRAY_ANNOTATION + \"(testClasses = {String.class, Long.class})\"));\n  }\n\n  @Test\n  public void testImportedClassArrayAnnotation() {\n    assertGeneratedMatches(\n        getImports(PropertyAnnotationsTest.class, Nullable.class),\n        ImmutableList.of(\n            TEST_ARRAY_ANNOTATION\n                + \"(testClasses = {javax.annotation.Nullable.class, Long.class})\"),\n        ImmutableList.of(TEST_ARRAY_ANNOTATION + \"(testClasses = {Nullable.class, Long.class})\"));\n  }\n\n  @Test\n  public void testEnumArrayAnnotation() {\n    assertGeneratedMatches(\n        getImports(PropertyAnnotationsTest.class),\n        ImmutableList.of(\n            TEST_ARRAY_ANNOTATION\n                + \"(testEnums = {PropertyAnnotationsTest.TestEnum.A,\"\n                + \" PropertyAnnotationsTest.TestEnum.B})\"),\n        ImmutableList.of(\n            TEST_ARRAY_ANNOTATION\n                + \"(testEnums = {PropertyAnnotationsTest.TestEnum.A,\"\n                + \" PropertyAnnotationsTest.TestEnum.B})\"));\n  }\n\n  @Test\n  public void testArrayOfEmptyAnnotationAnnotation() {\n    assertGeneratedMatches(\n        getImports(PropertyAnnotationsTest.class),\n        ImmutableList.of(\n            TEST_ARRAY_ANNOTATION\n                + \"(testAnnotations = {@PropertyAnnotationsTest.OtherAnnotation})\"),\n        ImmutableList.of(\n            TEST_ARRAY_ANNOTATION\n                + \"(testAnnotations = @PropertyAnnotationsTest.OtherAnnotation)\"));\n    assertGeneratedMatches(\n        getImports(PropertyAnnotationsTest.class),\n        ImmutableList.of(\n            TEST_ARRAY_ANNOTATION\n                + \"(testAnnotations = {@PropertyAnnotationsTest.OtherAnnotation,\"\n                + \" @PropertyAnnotationsTest.OtherAnnotation})\"),\n        ImmutableList.of(\n            TEST_ARRAY_ANNOTATION\n                + \"(testAnnotations = {@PropertyAnnotationsTest.OtherAnnotation,\"\n                + \" @PropertyAnnotationsTest.OtherAnnotation})\"));\n  }\n\n  @Test\n  public void testArrayOfValuedAnnotationAnnotation() {\n    assertGeneratedMatches(\n        getImports(PropertyAnnotationsTest.class),\n        ImmutableList.of(\n            TEST_ARRAY_ANNOTATION\n                + \"(testAnnotations = {@PropertyAnnotationsTest.OtherAnnotation(foo = 999)})\"),\n        ImmutableList.of(\n            TEST_ARRAY_ANNOTATION\n                + \"(testAnnotations = @PropertyAnnotationsTest.OtherAnnotation(foo = 999))\"));\n  }\n\n  /**\n   * Tests that when CopyAnnotations is present on a method, all non-inherited annotations (except\n   * those appearing in CopyAnnotations.exclude) are copied to the method implementation in the\n   * generated class.\n   */\n  @Test\n  public void testCopyingMethodAnnotations() {\n    ImmutableSet<String> imports = getImports(PropertyAnnotationsTest.class);\n    JavaFileObject inputFile =\n        new InputFileBuilder()\n            .setImports(imports)\n            .addAnnotations(\n                \"@AutoValue.CopyAnnotations(exclude=\"\n                    + \"{PropertyAnnotationsTest.TestAnnotation.class})\",\n                \"@Deprecated\",\n                \"@PropertyAnnotationsTest.TestAnnotation\",\n                \"@PropertyAnnotationsTest.InheritedAnnotation\")\n            .build();\n\n    // Annotations are in lexicographical order of FQN:\n    // @com.google.auto.value.processor.PropertyAnnotationsTest.InheritedAnnotation precedes\n    // @java.lang.Deprecated\n    JavaFileObject outputFile =\n        new OutputFileBuilder()\n            .setImports(imports)\n            .addMethodAnnotations(\"@PropertyAnnotationsTest.InheritedAnnotation\", \"@Deprecated\")\n            .addFieldAnnotations(\"@PropertyAnnotationsTest.InheritedAnnotation\", \"@Deprecated\")\n            .build();\n\n    Compilation compilation =\n        javac()\n            .withOptions(\"-A\" + Nullables.NULLABLE_OPTION)\n            .withProcessors(new AutoValueProcessor())\n            .compile(inputFile);\n    assertThat(compilation).succeeded();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Baz\")\n        .hasSourceEquivalentTo(outputFile);\n  }\n\n  /**\n   * Tests that when CopyAnnotationsToGeneratedField is present on a method, all non-inherited\n   * annotations (except those appearing in CopyAnnotationsToGeneratedField.exclude) are copied to\n   * the method implementation in the generated class.\n   */\n  @Test\n  public void testCopyingMethodAnnotationsToGeneratedFields() {\n    JavaFileObject inputFile =\n        new InputFileBuilder()\n            .setImports(getImports(PropertyAnnotationsTest.class, Target.class, ElementType.class))\n            .addAnnotations(\n                \"@AutoValue.CopyAnnotations(exclude={PropertyAnnotationsTest.\"\n                    + \"TestAnnotation.class})\",\n                \"@Deprecated\",\n                \"@PropertyAnnotationsTest.TestAnnotation\",\n                \"@PropertyAnnotationsTest.InheritedAnnotation\",\n                \"@MethodsOnly\")\n            .addInnerTypes(\"@Target(ElementType.METHOD) @interface MethodsOnly {}\")\n            .build();\n\n    // Annotations are in lexicographical order of FQN:\n    // @com.google.auto.value.processor.PropertyAnnotationsTest.InheritedAnnotation precedes\n    // @foo.bar.Baz.MethodsOnly precedes\n    // @java.lang.Deprecated\n    JavaFileObject outputFile =\n        new OutputFileBuilder()\n            .setImports(getImports(PropertyAnnotationsTest.class))\n            .addFieldAnnotations(\"@PropertyAnnotationsTest.InheritedAnnotation\", \"@Deprecated\")\n            .addMethodAnnotations(\n                \"@PropertyAnnotationsTest.InheritedAnnotation\", \"@Baz.MethodsOnly\", \"@Deprecated\")\n            .build();\n\n    Compilation compilation =\n        javac()\n            .withOptions(\"-A\" + Nullables.NULLABLE_OPTION + \"=\")\n            .withProcessors(new AutoValueProcessor())\n            .compile(inputFile);\n    assertThat(compilation).succeeded();\n    assertThat(compilation)\n        .generatedSourceFile(\"foo.bar.AutoValue_Baz\")\n        .hasSourceEquivalentTo(outputFile);\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/PropertyNamesTest.java",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.truth.Expect;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic class PropertyNamesTest {\n  @Rule public Expect expect = Expect.create();\n\n  private static final ImmutableMap<String, String> NORMAL_CASES =\n      ImmutableMap.<String, String>builder()\n          .put(\"Foo\", \"foo\")\n          .put(\"foo\", \"foo\")\n          .put(\"X\", \"x\")\n          .put(\"x\", \"x\")\n          .put(\"\", \"\")\n          .build();\n\n  @Test\n  public void decapitalizeLikeJavaBeans() {\n    NORMAL_CASES.forEach(\n        (input, output) ->\n            expect.that(PropertyNames.decapitalizeLikeJavaBeans(input)).isEqualTo(output));\n    expect.that(PropertyNames.decapitalizeLikeJavaBeans(null)).isNull();\n    expect.that(PropertyNames.decapitalizeLikeJavaBeans(\"HTMLPage\")).isEqualTo(\"HTMLPage\");\n    expect.that(PropertyNames.decapitalizeLikeJavaBeans(\"OAuth\")).isEqualTo(\"OAuth\");\n  }\n\n  @Test\n  public void decapitalizeNormally() {\n    NORMAL_CASES.forEach(\n        (input, output) ->\n            expect.that(PropertyNames.decapitalizeNormally(input)).isEqualTo(output));\n    expect.that(PropertyNames.decapitalizeNormally(null)).isNull();\n    expect.that(PropertyNames.decapitalizeNormally(\"HTMLPage\")).isEqualTo(\"hTMLPage\");\n    expect.that(PropertyNames.decapitalizeNormally(\"OAuth\")).isEqualTo(\"oAuth\");\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/ReformatterTest.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.truth.Truth.assertThat;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * Unit tests for {@link Reformatter}.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class ReformatterTest {\n  @Test\n  public void simple() {\n    String input =\n        \"\\n\"\n            + \"package com.latin.declension;  \\n\"\n            + \"\\n\"\n            + \"\\n\"\n            + \"public  class  Idem  {  \\n\"\n            + \"  \\n\"\n            + \"  Eadem   idem  ;  \\n\"\n            + \"\\n\"\n            + \"  Eundem eandem ( Idem  eiusdem  )  {\\n\"\n            + \"\\n\"\n            + \"    eiusdem (   eiusdem  )  ;  \\n\"\n            + \"\\n\"\n            + \"    eidem_eidem_eidem( ) ;\\n\"\n            + \"\\n\"\n            + \"  }\\n\"\n            + \"\\n\"\n            + \"\\n\"\n            + \"  Eodem ( Eadem eodem ) { }\\n\";\n    String output =\n        \"package com.latin.declension;\\n\"\n            + \"\\n\"\n            + \"public class Idem {\\n\"\n            + \"\\n\"\n            + \"  Eadem idem;\\n\"\n            + \"\\n\"\n            + \"  Eundem eandem (Idem eiusdem) {\\n\"\n            + \"    eiusdem (eiusdem);\\n\"\n            + \"    eidem_eidem_eidem();\\n\"\n            + \"  }\\n\"\n            + \"\\n\"\n            + \"  Eodem (Eadem eodem) { }\\n\";\n    assertThat(Reformatter.fixup(input)).isEqualTo(output);\n  }\n\n  @Test\n  public void specialSpaces() {\n    String input =\n        \"\\n\"\n            + \"package com.example.whatever;\\n\"\n            + \"\\n\"\n            + \"public class SomeClass {\\n\"\n            + \"  static final String STRING = \\\"  hello  world  \\\\n\\\";  \\n\"\n            + \"  static final String STRING_WITH_QUOTES = \\\" \\\\\\\"quote  me  now  \\\\\\\"  \\\"  ;\\n\"\n            + \"  static final int INT = /* not a string \\\" */  23  ;\\n\"\n            + \"  static final char QUOTE = '\\\"'  ;\\n\"\n            + \"  static final char QUOTE2 = '\\\\\\\"'  ;\\n\"\n            + \"}\\n\";\n    String output =\n        \"package com.example.whatever;\\n\"\n            + \"\\n\"\n            + \"public class SomeClass {\\n\"\n            + \"  static final String STRING = \\\"  hello  world  \\\\n\\\";\\n\"\n            + \"  static final String STRING_WITH_QUOTES = \\\" \\\\\\\"quote  me  now  \\\\\\\"  \\\";\\n\"\n            + \"  static final int INT = /* not a string \\\" */ 23;\\n\"\n            + \"  static final char QUOTE = '\\\"';\\n\"\n            + \"  static final char QUOTE2 = '\\\\\\\"';\\n\"\n            + \"}\\n\";\n    assertThat(Reformatter.fixup(input)).isEqualTo(output);\n  }\n\n  @Test\n  public void noTrailingNewline() {\n    String input = \"package com.example.whatever;\\n\\npublic class SomeClass {}\";\n    String output = input + \"\\n\";\n    assertThat(Reformatter.fixup(input)).isEqualTo(output);\n  }\n\n  @Test\n  public void indent() {\n    String input =\n        \"  class Test {\\n\"\n            + \"private final int field;\\n\"\n            + \"\\n\"\n            + \"Test(\\n\"\n            + \"@Interesting Integer field,\\n\"\n            + \"boolean ignored) {\\n\"\n            + \"this.field = field;\\n\"\n            + \"}\\n\"\n            + \"\\n\"\n            + \"@Override\\n\"\n            + \"public boolean equals(Object x) {\\n\"\n            + \"return x instanceof Test\\n\"\n            + \"&& ((Test) x).field == field;\\n\"\n            + \"// interesting\\n\"\n            + \"}\\n\"\n            + \"\\n\"\n            + \"@Override\\n\"\n            + \"public String toString() {\\n\"\n            + \"return \\\"Test{\\\"\\n\"\n            + \"+ \\\"field=\\\" + field\\n\"\n            + \"+ \\\"}\\\";\\n\"\n            + \"}\\n\"\n            + \"}\\n\";\n    String output =\n        \"class Test {\\n\"\n            + \"  private final int field;\\n\"\n            + \"\\n\"\n            + \"  Test(\\n\"\n            + \"      @Interesting Integer field,\\n\"\n            + \"      boolean ignored) {\\n\"\n            + \"    this.field = field;\\n\"\n            + \"  }\\n\"\n            + \"\\n\"\n            + \"  @Override\\n\"\n            + \"  public boolean equals(Object x) {\\n\"\n            + \"    return x instanceof Test\\n\"\n            + \"        && ((Test) x).field == field;\\n\"\n            + \"    // interesting\\n\"\n            + \"  }\\n\"\n            + \"\\n\"\n            + \"  @Override\\n\"\n            + \"  public String toString() {\\n\"\n            + \"    return \\\"Test{\\\"\\n\"\n            + \"        + \\\"field=\\\" + field\\n\"\n            + \"        + \\\"}\\\";\\n\"\n            + \"  }\\n\"\n            + \"}\\n\";\n    assertThat(Reformatter.fixup(input)).isEqualTo(output);\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/SimpleServiceLoaderTest.java",
    "content": "/*\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static java.util.stream.Collectors.toList;\nimport static org.junit.Assert.fail;\n\nimport com.google.common.collect.ImmutableList;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.OutputStreamWriter;\nimport java.io.PrintWriter;\nimport java.net.URL;\nimport java.net.URLClassLoader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Enumeration;\nimport java.util.List;\nimport java.util.ServiceConfigurationError;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarOutputStream;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic final class SimpleServiceLoaderTest {\n  @Test\n  public void loadOnce() throws Exception {\n    ClassLoader loader =\n        loaderForJarWithEntries(\n            CharSequence.class.getName(), String.class.getName(), StringBuilder.class.getName());\n\n    ImmutableList<CharSequence> providers = SimpleServiceLoader.load(CharSequence.class, loader);\n\n    // The provider entry for java.lang.String should have caused us to call new String(), which\n    // will produce this \"\" in the providers.\n    assertThat(providers).contains(\"\");\n    List<Class<?>> classes = providers.stream().map(Object::getClass).collect(toList());\n    assertThat(classes).containsExactly(String.class, StringBuilder.class).inOrder();\n  }\n\n  // Sometimes you can have the same jar appear more than once in the classpath, perhaps in\n  // different versions. In that case we don't want to instantiate the same class more than once.\n  // This test checks that we don't.\n  @Test\n  public void loadWithDuplicates() throws Exception {\n    ClassLoader loader1 =\n        loaderForJarWithEntries(\n            CharSequence.class.getName(), String.class.getName(), StringBuilder.class.getName());\n    ClassLoader loader2 =\n        loaderForJarWithEntries(\n            CharSequence.class.getName(), String.class.getName(), StringBuilder.class.getName());\n    ClassLoader combinedLoader =\n        new ClassLoader() {\n          @Override\n          public Enumeration<URL> getResources(String name) throws IOException {\n            List<URL> urls = new ArrayList<>(Collections.list(loader1.getResources(name)));\n            urls.addAll(Collections.list(loader2.getResources(name)));\n            return Collections.enumeration(urls);\n          }\n        };\n\n    ImmutableList<CharSequence> providers =\n        SimpleServiceLoader.load(CharSequence.class, combinedLoader);\n\n    assertThat(providers).contains(\"\");\n    List<Class<?>> classes = providers.stream().map(Object::getClass).collect(toList());\n    assertThat(classes).containsExactly(String.class, StringBuilder.class).inOrder();\n  }\n\n  @Test\n  public void blankLinesAndComments() throws Exception {\n    ClassLoader loader =\n        loaderForJarWithEntries(\n            CharSequence.class.getName(),\n            \"\",\n            \"# this is a comment\",\n            \"   # this is also a comment\",\n            \"  java.lang.String  # this is a comment after a class name\");\n\n    ImmutableList<CharSequence> providers = SimpleServiceLoader.load(CharSequence.class, loader);\n\n    assertThat(providers).containsExactly(\"\");\n  }\n\n  @Test\n  public void loadTwiceFromSameLoader() throws Exception {\n    ClassLoader loader =\n        loaderForJarWithEntries(\n            CharSequence.class.getName(), String.class.getName(), StringBuilder.class.getName());\n\n    ImmutableList<CharSequence> providers1 = SimpleServiceLoader.load(CharSequence.class, loader);\n    ImmutableList<CharSequence> providers2 = SimpleServiceLoader.load(CharSequence.class, loader);\n\n    List<Class<?>> classes1 = providers1.stream().map(Object::getClass).collect(toList());\n    List<Class<?>> classes2 = providers2.stream().map(Object::getClass).collect(toList());\n    assertThat(classes2).containsExactlyElementsIn(classes1).inOrder();\n  }\n\n  @Test\n  public void loadTwiceFromDifferentLoaders() throws Exception {\n    URL jarUrl =\n        urlForJarWithEntries(\n            CharSequence.class.getName(), String.class.getName(), StringBuilder.class.getName());\n    ClassLoader loader1 = new URLClassLoader(new URL[] {jarUrl});\n\n    ImmutableList<CharSequence> providers1 = SimpleServiceLoader.load(CharSequence.class, loader1);\n    // We should have called `new String()`, so the result should contain \"\".\n    assertThat(providers1).contains(\"\");\n\n    ClassLoader loader2 = new URLClassLoader(new URL[] {jarUrl});\n    ImmutableList<CharSequence> providers2 = SimpleServiceLoader.load(CharSequence.class, loader2);\n\n    List<Class<?>> classes1 = providers1.stream().map(Object::getClass).collect(toList());\n    List<Class<?>> classes2 = providers2.stream().map(Object::getClass).collect(toList());\n    assertThat(classes2).containsExactlyElementsIn(classes1).inOrder();\n  }\n\n  @Test\n  public void noProviders() throws Exception {\n    ClassLoader loader = loaderForJarWithEntries(CharSequence.class.getName());\n\n    ImmutableList<CharSequence> providers = SimpleServiceLoader.load(CharSequence.class, loader);\n\n    assertThat(providers).isEmpty();\n  }\n\n  @Test\n  public void classNotFound() throws Exception {\n    ClassLoader loader =\n        loaderForJarWithEntries(CharSequence.class.getName(), \"this.is.not.a.Class\");\n\n    try {\n      SimpleServiceLoader.load(CharSequence.class, loader);\n      fail();\n    } catch (ServiceConfigurationError expected) {\n      assertThat(expected).hasMessageThat().startsWith(\"Could not load \");\n    }\n  }\n\n  @Test\n  public void wrongTypeClass() throws Exception {\n    ClassLoader loader = loaderForJarWithEntries(CharSequence.class.getName(), \"java.lang.Thread\");\n\n    try {\n      SimpleServiceLoader.load(CharSequence.class, loader);\n      fail();\n    } catch (ServiceConfigurationError expected) {\n      assertThat(expected).hasMessageThat().startsWith(\"Class java.lang.Thread is not assignable\");\n    }\n  }\n\n  @Test\n  public void couldNotConstruct() throws Exception {\n    ClassLoader loader = loaderForJarWithEntries(\"java.lang.System\", \"java.lang.System\");\n\n    try {\n      SimpleServiceLoader.load(System.class, loader);\n      fail();\n    } catch (ServiceConfigurationError expected) {\n      assertThat(expected).hasMessageThat().startsWith(\"Could not construct\");\n    }\n  }\n\n  @Test\n  public void brokenLoader() {\n    ClassLoader loader =\n        new URLClassLoader(new URL[0]) {\n          @Override\n          public Enumeration<URL> getResources(String name) throws IOException {\n            throw new IOException(\"bang\");\n          }\n        };\n\n    try {\n      SimpleServiceLoader.load(CharSequence.class, loader);\n      fail();\n    } catch (ServiceConfigurationError expected) {\n      assertThat(expected).hasMessageThat().startsWith(\"Could not look up\");\n      assertThat(expected).hasCauseThat().hasMessageThat().isEqualTo(\"bang\");\n    }\n  }\n\n  private static ClassLoader loaderForJarWithEntries(String service, String... lines)\n      throws IOException {\n    URL jarUrl = urlForJarWithEntries(service, lines);\n    return new URLClassLoader(new URL[] {jarUrl});\n  }\n\n  private static URL urlForJarWithEntries(String service, String... lines) throws IOException {\n    File jar = File.createTempFile(\"SimpleServiceLoaderTest\", \"jar\");\n    jar.deleteOnExit();\n    try (JarOutputStream out = new JarOutputStream(new FileOutputStream(jar))) {\n      JarEntry jarEntry = new JarEntry(\"META-INF/services/\" + service);\n      out.putNextEntry(jarEntry);\n      // It would be bad practice to use try-with-resources below, because closing the PrintWriter\n      // would close the JarOutputStream.\n      PrintWriter writer = new PrintWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));\n      for (String line : lines) {\n        writer.println(line);\n      }\n      writer.flush();\n    }\n    return jar.toURI().toURL();\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/SimplifyWithAnnotationsTest.java",
    "content": "/*\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.collect.MoreCollectors.onlyElement;\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.testing.compile.CompilationSubject.assertThat;\nimport static com.google.testing.compile.Compiler.javac;\nimport static javax.lang.model.util.ElementFilter.fieldsIn;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.truth.Expect;\nimport com.google.testing.compile.JavaFileObjects;\nimport java.util.Set;\nimport javax.annotation.processing.AbstractProcessor;\nimport javax.annotation.processing.RoundEnvironment;\nimport javax.annotation.processing.SupportedAnnotationTypes;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.ElementFilter;\nimport javax.tools.JavaFileObject;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * This test verifies the method {@link TypeEncoder#encodeWithAnnotations(TypeMirror).\n * It takes a list of \"type spellings\", like {@code @Nullable String}, and compiles a class\n * with one field for each spelling. So there might be a field {@code @Nullable String x2;}.\n * Then it examines each compiled field to extract its {@code TypeMirror}, and uses the\n * {@code TypeSimplifier} method to reconvert that into a string. It should get back the same\n * type spelling in each case.\n *\n * <p>I originally tried to write a less convoluted test using compile-testing. In my test,\n * each type to be tested was an actual type in the test class (the type of a field, or the\n * return type of a method). However, I found that if I examined these types by looking up a class\n * with {@link javax.lang.model.util.Elements#getTypeElement} and following through to the type\n * of interest, it never had any type annotations.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class SimplifyWithAnnotationsTest {\n  @Rule public final Expect expect = Expect.create();\n\n  /**\n   * The types that we will compile and then recreate. They are referenced in a context where {@code\n   * Set} is unambiguous but not {@code List}, which allows us to test the placement of annotations\n   * in unqualified types like {@code Set<T>} and qualified types like {@code java.util.List<T>}.\n   */\n  private static final ImmutableList<String> TYPE_SPELLINGS =\n      ImmutableList.of(\n          \"Object\",\n          \"Set\",\n          \"String\",\n          \"Nullable\",\n          \"@Nullable String\",\n          \"String[]\",\n          \"@Nullable String[]\",\n          \"String @Nullable []\",\n          \"String @Nullable [] @Nullable []\",\n          \"java.awt.List\",\n          \"java.util.List<String>\",\n          \"Set<@Nullable String>\",\n          \"@Nullable Set<String>\",\n          \"int\",\n          \"@Nullable int\", // whatever that might mean\n          \"@Nullable int[]\",\n          \"int @Nullable []\",\n          \"T\",\n          \"@Nullable T\",\n          \"Set<@Nullable T>\",\n          \"Set<? extends @Nullable T>\",\n          \"Set<? extends @Nullable String>\",\n          \"Set<? extends @Nullable String @Nullable []>\",\n          \"java.util.@Nullable List<@Nullable T>\",\n          \"java.util.@Nullable List<java.util.@Nullable List<T>>\");\n\n  private static final JavaFileObject NULLABLE_FILE_OBJECT =\n      JavaFileObjects.forSourceLines(\n          \"pkg.Nullable\",\n          \"package pkg;\",\n          \"\",\n          \"import java.lang.annotation.ElementType;\",\n          \"import java.lang.annotation.Target;\",\n          \"\",\n          \"@Target(ElementType.TYPE_USE)\",\n          \"public @interface Nullable {}\");\n\n  private static final JavaFileObject TEST_CLASS_FILE_OBJECT =\n      JavaFileObjects.forSourceLines(\"pkg.TestClass\", buildTestClass());\n\n  private static ImmutableList<String> buildTestClass() {\n    // Some older versions of javac don't handle type annotations at all well in annotation\n    // processors. The `witness` method in the generated class is there to detect that, and\n    // skip the test if it is the case.\n    ImmutableList.Builder<String> builder = ImmutableList.builder();\n    builder.add(\n        \"package pkg;\",\n        \"\",\n        \"import java.util.Set;\",\n        \"\",\n        \"public abstract class TestClass<T> {\",\n        \"  abstract @Nullable T witness();\");\n    int i = 0;\n    for (String typeSpelling : TYPE_SPELLINGS) {\n      builder.add(String.format(\"  %s x%d;\\n\", typeSpelling, i++));\n    }\n    builder.add(\"}\");\n    return builder.build();\n  }\n\n  @Test\n  public void testSimplifyWithAnnotations() {\n    // The real test happens inside the .compile(...), by virtue of TestProcessor.\n    assertThat(\n            javac()\n                .withOptions(\"-proc:only\")\n                .withProcessors(new TestProcessor())\n                .compile(NULLABLE_FILE_OBJECT, TEST_CLASS_FILE_OBJECT))\n        .succeededWithoutWarnings();\n  }\n\n  @SupportedAnnotationTypes(\"*\")\n  private static class TestProcessor extends AbstractProcessor {\n    @Override\n    public SourceVersion getSupportedSourceVersion() {\n      return SourceVersion.latest();\n    }\n\n    @Override\n    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n      if (roundEnv.processingOver()) {\n        TypeElement testClass = processingEnv.getElementUtils().getTypeElement(\"pkg.TestClass\");\n        testTypeSpellings(testClass);\n      }\n      return false;\n    }\n\n    void testTypeSpellings(TypeElement testClass) {\n      ExecutableElement witness =\n          ElementFilter.methodsIn(testClass.getEnclosedElements()).stream()\n              .filter(m -> m.getSimpleName().contentEquals(\"witness\"))\n              .collect(onlyElement());\n      if (witness.getReturnType().getAnnotationMirrors().isEmpty()) {\n        System.err.println(\"SKIPPING TEST BECAUSE OF BUGGY COMPILER\");\n        return;\n      }\n      ImmutableMap<String, TypeMirror> typeSpellingToType = typesFromTestClass(testClass);\n      assertThat(typeSpellingToType).isNotEmpty();\n      StringBuilder text = new StringBuilder();\n      StringBuilder expected = new StringBuilder();\n      // Build up a fake source text with the encodings for the types in it, and decode it to\n      // ensure the type spellings are what we expect.\n      typeSpellingToType.forEach(\n          (typeSpelling, type) -> {\n            text.append(\"{\").append(TypeEncoder.encodeWithAnnotations(type)).append(\"}\");\n            expected.append(\"{\").append(typeSpelling).append(\"}\");\n          });\n      String decoded = TypeEncoder.decode(text.toString(), processingEnv, \"pkg\", null);\n      assertThat(decoded).isEqualTo(expected.toString());\n    }\n\n    private static ImmutableMap<String, TypeMirror> typesFromTestClass(TypeElement type) {\n      // Reads the types of the fields from the compiled TestClass and uses them to produce\n      // a map from type spellings to types. This method depends on type.getEnclosedElements()\n      // returning the fields in source order, which it is specified to do.\n      ImmutableMap.Builder<String, TypeMirror> typeSpellingToTypeBuilder = ImmutableMap.builder();\n      int i = 0;\n      for (VariableElement field : fieldsIn(type.getEnclosedElements())) {\n        String spelling = TYPE_SPELLINGS.get(i);\n        typeSpellingToTypeBuilder.put(spelling, field.asType());\n        i++;\n      }\n      return typeSpellingToTypeBuilder.build();\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/TemplateVarsTest.java",
    "content": "/*\n * Copyright 2014 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.fail;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.escapevelocity.Template;\nimport java.io.IOException;\nimport java.io.Reader;\nimport java.io.StringReader;\nimport java.util.List;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * Tests for FieldReader.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class TemplateVarsTest {\n  static class HappyVars extends TemplateVars {\n    Integer integer;\n    String string;\n    List<Integer> list;\n    private static final String IGNORED_STATIC_FINAL = \"hatstand\";\n\n    @Override\n    Template parsedTemplate() {\n      return parsedTemplateForString(\"integer=$integer string=$string list=$list\");\n    }\n  }\n\n  static Template parsedTemplateForString(String string) {\n    try {\n      Reader reader = new StringReader(string);\n      return Template.parseFrom(reader);\n    } catch (IOException e) {\n      throw new AssertionError(e);\n    }\n  }\n\n  @Test\n  public void testHappy() {\n    HappyVars happy = new HappyVars();\n    happy.integer = 23;\n    happy.string = \"wibble\";\n    happy.list = ImmutableList.of(5, 17, 23);\n    assertThat(HappyVars.IGNORED_STATIC_FINAL).isEqualTo(\"hatstand\"); // avoids unused warning\n    String expectedText = \"integer=23 string=wibble list=[5, 17, 23]\";\n    String actualText = happy.toText();\n    assertThat(actualText).isEqualTo(expectedText);\n  }\n\n  @Test\n  public void testUnset() {\n    HappyVars sad = new HappyVars();\n    sad.integer = 23;\n    sad.list = ImmutableList.of(23);\n    try {\n      sad.toText();\n      fail(\"Did not get expected exception\");\n    } catch (IllegalArgumentException expected) {\n    }\n  }\n\n  static class SubHappyVars extends HappyVars {\n    Character character;\n\n    @Override\n    Template parsedTemplate() {\n      return parsedTemplateForString(\n          \"integer=$integer string=$string list=$list character=$character\");\n    }\n  }\n\n  @Test\n  public void testSubSub() {\n    SubHappyVars vars = new SubHappyVars();\n    vars.integer = 23;\n    vars.string = \"wibble\";\n    vars.list = ImmutableList.of(5, 17, 23);\n    vars.character = 'ß';\n    String expectedText = \"integer=23 string=wibble list=[5, 17, 23] character=ß\";\n    String actualText = vars.toText();\n    assertThat(actualText).isEqualTo(expectedText);\n  }\n\n  static class Private extends TemplateVars {\n    Integer integer;\n    private String unusedString;\n\n    @Override\n    Template parsedTemplate() {\n      throw new UnsupportedOperationException();\n    }\n  }\n\n  @Test\n  public void testPrivate() {\n    try {\n      new Private();\n      fail(\"Did not get expected exception\");\n    } catch (IllegalArgumentException expected) {\n    }\n  }\n\n  static class Static extends TemplateVars {\n    Integer integer;\n    static String string;\n\n    @Override\n    Template parsedTemplate() {\n      throw new UnsupportedOperationException();\n    }\n  }\n\n  @Test\n  public void testStatic() {\n    try {\n      new Static();\n      fail(\"Did not get expected exception\");\n    } catch (IllegalArgumentException expected) {\n    }\n  }\n\n  static class Primitive extends TemplateVars {\n    int integer;\n    String string;\n\n    @Override\n    Template parsedTemplate() {\n      throw new UnsupportedOperationException();\n    }\n  }\n\n  @Test\n  public void testPrimitive() {\n    try {\n      new Primitive();\n      fail(\"Did not get expected exception\");\n    } catch (IllegalArgumentException expected) {\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/TypeEncoderTest.java",
    "content": "/*\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.testing.compile.CompilationSubject.assertThat;\nimport static com.google.testing.compile.Compiler.javac;\nimport static java.util.stream.Collectors.joining;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.auto.value.processor.MissingTypes.MissingTypeException;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.testing.compile.Compilation;\nimport com.google.testing.compile.CompilationRule;\nimport com.google.testing.compile.JavaFileObjects;\nimport java.util.List;\nimport java.util.Set;\nimport javax.annotation.processing.AbstractProcessor;\nimport javax.annotation.processing.RoundEnvironment;\nimport javax.annotation.processing.SupportedAnnotationTypes;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.ErrorType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.Types;\nimport javax.tools.Diagnostic;\nimport javax.tools.JavaFileObject;\nimport org.junit.Before;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * Tests for {@link TypeEncoder}.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class TypeEncoderTest {\n  @Rule public final CompilationRule compilationRule = new CompilationRule();\n\n  private Types typeUtils;\n  private Elements elementUtils;\n\n  @Before\n  public void setUp() {\n    typeUtils = compilationRule.getTypes();\n    elementUtils = compilationRule.getElements();\n  }\n\n  /**\n   * Assert that the fake program returned by fakeProgramForTypes has the given list of imports and\n   * the given list of spellings. Here, \"spellings\" means the way each type is referenced in the\n   * decoded program, for example {@code Timer} if {@code java.util.Timer} can be imported, or\n   * {@code java.util.Timer} if not.\n   *\n   * <p>We construct a fake program that references each of the given types in turn.\n   * TypeEncoder.decode doesn't have any real notion of Java syntax, so our program just consists of\n   * START and END markers around the {@code `import`} tag, followed by each type in braces, as\n   * encoded by TypeEncoder.encode. Once decoded, the program should consist of the appropriate\n   * imports (inside START...END) and each type in braces, spelled appropriately.\n   *\n   * @param fakePackage the package that TypeEncoder should consider the fake program to be in.\n   *     Classes in the same package don't usually need to be imported.\n   */\n  private void assertTypeImportsAndSpellings(\n      Set<TypeMirror> types, String fakePackage, List<String> imports, List<String> spellings) {\n    String fakeProgram =\n        \"START\\n`import`\\nEND\\n\"\n            + types.stream().map(TypeEncoder::encode).collect(joining(\"}\\n{\", \"{\", \"}\"));\n    String decoded =\n        TypeEncoder.decode(\n            fakeProgram, elementUtils, typeUtils, fakePackage, baseWithoutContainedTypes());\n    String expected =\n        \"START\\n\"\n            + imports.stream().map(s -> \"import \" + s + \";\\n\").collect(joining())\n            + \"\\nEND\\n\"\n            + spellings.stream().collect(joining(\"}\\n{\", \"{\", \"}\"));\n    assertThat(decoded).isEqualTo(expected);\n  }\n\n  private static class MultipleBounds<K extends List<V> & Comparable<K>, V> {}\n\n  @Test\n  public void testImportsForNoTypes() {\n    assertTypeImportsAndSpellings(\n        typeMirrorSet(), \"foo.bar\", ImmutableList.of(), ImmutableList.of());\n  }\n\n  @Test\n  public void testImportsForImplicitlyImportedTypes() {\n    Set<TypeMirror> types =\n        typeMirrorSet(\n            typeMirrorOf(java.lang.String.class),\n            typeMirrorOf(javax.management.MBeanServer.class), // Same package, so no import.\n            typeUtils.getPrimitiveType(TypeKind.INT),\n            typeUtils.getPrimitiveType(TypeKind.BOOLEAN));\n    assertTypeImportsAndSpellings(\n        types,\n        \"javax.management\",\n        ImmutableList.of(),\n        ImmutableList.of(\"String\", \"MBeanServer\", \"int\", \"boolean\"));\n  }\n\n  @Test\n  public void testImportsForPlainTypes() {\n    Set<TypeMirror> types =\n        typeMirrorSet(\n            typeUtils.getPrimitiveType(TypeKind.INT),\n            typeMirrorOf(java.lang.String.class),\n            typeMirrorOf(java.net.Proxy.class),\n            typeMirrorOf(java.net.Proxy.Type.class),\n            typeMirrorOf(java.util.regex.Pattern.class),\n            typeMirrorOf(javax.management.MBeanServer.class));\n    assertTypeImportsAndSpellings(\n        types,\n        \"foo.bar\",\n        ImmutableList.of(\n            \"java.net.Proxy\", \"java.util.regex.Pattern\", \"javax.management.MBeanServer\"),\n        ImmutableList.of(\"int\", \"String\", \"Proxy\", \"Proxy.Type\", \"Pattern\", \"MBeanServer\"));\n  }\n\n  @Test\n  public void testImportsForComplicatedTypes() {\n    TypeElement list = typeElementOf(java.util.List.class);\n    TypeElement map = typeElementOf(java.util.Map.class);\n    Set<TypeMirror> types =\n        typeMirrorSet(\n            typeUtils.getPrimitiveType(TypeKind.INT),\n            typeMirrorOf(java.util.regex.Pattern.class),\n            typeUtils.getDeclaredType(\n                list, // List<Timer>\n                typeMirrorOf(java.util.Timer.class)),\n            typeUtils.getDeclaredType(\n                map, // Map<? extends Timer, ? super BigInteger>\n                typeUtils.getWildcardType(typeMirrorOf(java.util.Timer.class), null),\n                typeUtils.getWildcardType(null, typeMirrorOf(java.math.BigInteger.class))));\n    // Timer is referenced twice but should obviously only be imported once.\n    assertTypeImportsAndSpellings(\n        types,\n        \"foo.bar\",\n        ImmutableList.of(\n            \"java.math.BigInteger\",\n            \"java.util.List\",\n            \"java.util.Map\",\n            \"java.util.Timer\",\n            \"java.util.regex.Pattern\"),\n        ImmutableList.of(\n            \"int\", \"Pattern\", \"List<Timer>\", \"Map<? extends Timer, ? super BigInteger>\"));\n  }\n\n  @Test\n  public void testImportsForArrayTypes() {\n    TypeElement list = typeElementOf(java.util.List.class);\n    TypeElement set = typeElementOf(java.util.Set.class);\n    Set<TypeMirror> types =\n        typeMirrorSet(\n            typeUtils.getArrayType(typeUtils.getPrimitiveType(TypeKind.INT)),\n            typeUtils.getArrayType(typeMirrorOf(java.util.regex.Pattern.class)),\n            typeUtils.getArrayType( // Set<Matcher[]>[]\n                typeUtils.getDeclaredType(\n                    set, typeUtils.getArrayType(typeMirrorOf(java.util.regex.Matcher.class)))),\n            typeUtils.getDeclaredType(\n                list, // List<Timer[]>\n                typeUtils.getArrayType(typeMirrorOf(java.util.Timer.class))));\n    // Timer is referenced twice but should obviously only be imported once.\n    assertTypeImportsAndSpellings(\n        types,\n        \"foo.bar\",\n        ImmutableList.of(\n            \"java.util.List\",\n            \"java.util.Set\",\n            \"java.util.Timer\",\n            \"java.util.regex.Matcher\",\n            \"java.util.regex.Pattern\"),\n        ImmutableList.of(\"int[]\", \"Pattern[]\", \"Set<Matcher[]>[]\", \"List<Timer[]>\"));\n  }\n\n  @Test\n  public void testImportNestedType() {\n    Set<TypeMirror> types = typeMirrorSet(typeMirrorOf(java.net.Proxy.Type.class));\n    assertTypeImportsAndSpellings(\n        types, \"foo.bar\", ImmutableList.of(\"java.net.Proxy\"), ImmutableList.of(\"Proxy.Type\"));\n  }\n\n  @Test\n  public void testImportsForAmbiguousNames() {\n    TypeMirror wildcard = typeUtils.getWildcardType(null, null);\n    Set<TypeMirror> types =\n        typeMirrorSet(\n            typeUtils.getPrimitiveType(TypeKind.INT),\n            typeMirrorOf(java.awt.List.class),\n            typeMirrorOf(java.lang.String.class),\n            typeUtils.getDeclaredType( // List<?>\n                typeElementOf(java.util.List.class), wildcard),\n            typeUtils.getDeclaredType( // Map<?, ?>\n                typeElementOf(java.util.Map.class), wildcard, wildcard));\n    assertTypeImportsAndSpellings(\n        types,\n        \"foo.bar\",\n        ImmutableList.of(\"java.util.Map\"),\n        ImmutableList.of(\"int\", \"java.awt.List\", \"String\", \"java.util.List<?>\", \"Map<?, ?>\"));\n  }\n\n  @Test\n  public void testSimplifyJavaLangString() {\n    Set<TypeMirror> types = typeMirrorSet(typeMirrorOf(java.lang.String.class));\n    assertTypeImportsAndSpellings(types, \"foo.bar\", ImmutableList.of(), ImmutableList.of(\"String\"));\n  }\n\n  @Test\n  public void testSimplifyJavaLangThreadState() {\n    Set<TypeMirror> types = typeMirrorSet(typeMirrorOf(java.lang.Thread.State.class));\n    assertTypeImportsAndSpellings(\n        types, \"foo.bar\", ImmutableList.of(), ImmutableList.of(\"Thread.State\"));\n  }\n\n  @Test\n  public void testSimplifyJavaLangNamesake() {\n    TypeMirror javaLangType = typeMirrorOf(java.lang.RuntimePermission.class);\n    TypeMirror notJavaLangType =\n        typeMirrorOf(com.google.auto.value.processor.testclasses.RuntimePermission.class);\n    Set<TypeMirror> types = typeMirrorSet(javaLangType, notJavaLangType);\n    assertTypeImportsAndSpellings(\n        types,\n        \"foo.bar\",\n        ImmutableList.of(),\n        ImmutableList.of(javaLangType.toString(), notJavaLangType.toString()));\n  }\n\n  @Test\n  public void testSimplifyComplicatedTypes() {\n    // This test constructs a set of types and feeds them to TypeEncoder. Then it verifies that\n    // the resultant rewrites of those types are what we would expect.\n    TypeElement list = typeElementOf(java.util.List.class);\n    TypeElement map = typeElementOf(java.util.Map.class);\n    TypeMirror string = typeMirrorOf(java.lang.String.class);\n    TypeMirror integer = typeMirrorOf(java.lang.Integer.class);\n    TypeMirror pattern = typeMirrorOf(java.util.regex.Pattern.class);\n    TypeMirror timer = typeMirrorOf(java.util.Timer.class);\n    TypeMirror bigInteger = typeMirrorOf(java.math.BigInteger.class);\n    ImmutableMap<TypeMirror, String> typeMap =\n        ImmutableMap.<TypeMirror, String>builder()\n            .put(typeUtils.getPrimitiveType(TypeKind.INT), \"int\")\n            .put(typeUtils.getArrayType(typeUtils.getPrimitiveType(TypeKind.BYTE)), \"byte[]\")\n            .put(pattern, \"Pattern\")\n            .put(typeUtils.getArrayType(pattern), \"Pattern[]\")\n            .put(typeUtils.getArrayType(typeUtils.getArrayType(pattern)), \"Pattern[][]\")\n            .put(typeUtils.getDeclaredType(list, typeUtils.getWildcardType(null, null)), \"List<?>\")\n            .put(typeUtils.getDeclaredType(list, timer), \"List<Timer>\")\n            .put(typeUtils.getDeclaredType(map, string, integer), \"Map<String, Integer>\")\n            .put(\n                typeUtils.getDeclaredType(\n                    map,\n                    typeUtils.getWildcardType(timer, null),\n                    typeUtils.getWildcardType(null, bigInteger)),\n                \"Map<? extends Timer, ? super BigInteger>\")\n            .build();\n    assertTypeImportsAndSpellings(\n        typeMap.keySet(),\n        \"foo.bar\",\n        ImmutableList.of(\n            \"java.math.BigInteger\",\n            \"java.util.List\",\n            \"java.util.Map\",\n            \"java.util.Timer\",\n            \"java.util.regex.Pattern\"),\n        ImmutableList.copyOf(typeMap.values()));\n  }\n\n  @Test\n  public void testSimplifyMultipleBounds() {\n    TypeElement multipleBoundsElement = typeElementOf(MultipleBounds.class);\n    TypeMirror multipleBoundsMirror = multipleBoundsElement.asType();\n    String text = \"`import`\\n\";\n    text += \"{\" + TypeEncoder.encode(multipleBoundsMirror) + \"}\";\n    text += \"{\" + TypeEncoder.typeParametersString(multipleBoundsElement.getTypeParameters()) + \"}\";\n    String myPackage = getClass().getPackage().getName();\n    String decoded =\n        TypeEncoder.decode(text, elementUtils, typeUtils, myPackage, baseWithoutContainedTypes());\n    String expected =\n        \"import java.util.List;\\n\\n\"\n            + \"{TypeEncoderTest.MultipleBounds<K, V>}\"\n            + \"{<K extends List<V> & Comparable<K>, V>}\";\n    assertThat(decoded).isEqualTo(expected);\n  }\n\n  @SuppressWarnings(\"ClassCanBeStatic\")\n  static class Outer<T extends Number> {\n    class InnerWithoutTypeParam {}\n\n    class Middle<U> {\n      class InnerWithTypeParam<V> {}\n    }\n  }\n\n  @Test\n  public void testOuterParameterizedInnerNot() {\n    TypeElement outerElement = typeElementOf(Outer.class);\n    DeclaredType doubleMirror = typeMirrorOf(Double.class);\n    DeclaredType outerOfDoubleMirror = typeUtils.getDeclaredType(outerElement, doubleMirror);\n    TypeElement innerWithoutTypeParamElement = typeElementOf(Outer.InnerWithoutTypeParam.class);\n    DeclaredType parameterizedInnerWithoutTypeParam =\n        typeUtils.getDeclaredType(outerOfDoubleMirror, innerWithoutTypeParamElement);\n    String encoded = TypeEncoder.encode(parameterizedInnerWithoutTypeParam);\n    String myPackage = getClass().getPackage().getName();\n    String decoded =\n        TypeEncoder.decode(\n            encoded, elementUtils, typeUtils, myPackage, baseWithoutContainedTypes());\n    String expected = \"TypeEncoderTest.Outer<Double>.InnerWithoutTypeParam\";\n    assertThat(decoded).isEqualTo(expected);\n  }\n\n  @Test\n  public void testOuterParameterizedInnerAlso() {\n    TypeElement outerElement = typeElementOf(Outer.class);\n    DeclaredType doubleMirror = typeMirrorOf(Double.class);\n    DeclaredType outerOfDoubleMirror = typeUtils.getDeclaredType(outerElement, doubleMirror);\n    TypeElement middleElement = typeElementOf(Outer.Middle.class);\n    DeclaredType stringMirror = typeMirrorOf(String.class);\n    DeclaredType middleOfStringMirror =\n        typeUtils.getDeclaredType(outerOfDoubleMirror, middleElement, stringMirror);\n    TypeElement innerWithTypeParamElement = typeElementOf(Outer.Middle.InnerWithTypeParam.class);\n    DeclaredType integerMirror = typeMirrorOf(Integer.class);\n    DeclaredType parameterizedInnerWithTypeParam =\n        typeUtils.getDeclaredType(middleOfStringMirror, innerWithTypeParamElement, integerMirror);\n    String encoded = TypeEncoder.encode(parameterizedInnerWithTypeParam);\n    String myPackage = getClass().getPackage().getName();\n    String decoded =\n        TypeEncoder.decode(\n            encoded, elementUtils, typeUtils, myPackage, baseWithoutContainedTypes());\n    String expected = \"TypeEncoderTest.Outer<Double>.Middle<String>.InnerWithTypeParam<Integer>\";\n    assertThat(decoded).isEqualTo(expected);\n  }\n\n  private static Set<TypeMirror> typeMirrorSet(TypeMirror... typeMirrors) {\n    Set<TypeMirror> set = new TypeMirrorSet();\n    for (TypeMirror typeMirror : typeMirrors) {\n      assertThat(set.add(typeMirror)).isTrue();\n    }\n    return set;\n  }\n\n  private TypeElement typeElementOf(Class<?> c) {\n    return elementUtils.getTypeElement(c.getCanonicalName());\n  }\n\n  private DeclaredType typeMirrorOf(Class<?> c) {\n    return MoreTypes.asDeclared(typeElementOf(c).asType());\n  }\n\n  /**\n   * Returns a \"base type\" for TypeSimplifier that does not contain any nested types. The point\n   * being that every {@code TypeSimplifier} has a base type that the class being generated is going\n   * to extend, and if that class has nested types they will be in scope, and therefore a possible\n   * source of ambiguity.\n   */\n  private TypeMirror baseWithoutContainedTypes() {\n    return typeMirrorOf(Object.class);\n  }\n\n  // This test checks that we correctly throw MissingTypeException if there is an ErrorType anywhere\n  // inside a type we are asked to simplify. There's no way to get an ErrorType from typeUtils or\n  // elementUtils, so we need to fire up the compiler with an erroneous source file and use an\n  // annotation processor to capture the resulting ErrorType. Then we can run tests within that\n  // annotation processor, and propagate any failures out of this test.\n  @Test\n  public void testErrorTypes() {\n    JavaFileObject source =\n        JavaFileObjects.forSourceString(\n            \"ExtendsUndefinedType\", \"class ExtendsUndefinedType extends UndefinedParent {}\");\n    Compilation compilation = javac().withProcessors(new ErrorTestProcessor()).compile(source);\n    assertThat(compilation).failed();\n    assertThat(compilation).hadErrorContaining(\"UndefinedParent\");\n    assertThat(compilation).hadErrorCount(1);\n  }\n\n  @SupportedAnnotationTypes(\"*\")\n  private static class ErrorTestProcessor extends AbstractProcessor {\n    Types typeUtils;\n    Elements elementUtils;\n\n    @Override\n    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n      if (roundEnv.processingOver()) {\n        typeUtils = processingEnv.getTypeUtils();\n        elementUtils = processingEnv.getElementUtils();\n        test();\n      }\n      return false;\n    }\n\n    private void test() {\n      TypeElement extendsUndefinedType = elementUtils.getTypeElement(\"ExtendsUndefinedType\");\n      ErrorType errorType = (ErrorType) extendsUndefinedType.getSuperclass();\n      TypeElement list = elementUtils.getTypeElement(\"java.util.List\");\n      TypeMirror listOfError = typeUtils.getDeclaredType(list, errorType);\n      TypeMirror queryExtendsError = typeUtils.getWildcardType(errorType, null);\n      TypeMirror listOfQueryExtendsError = typeUtils.getDeclaredType(list, queryExtendsError);\n      TypeMirror querySuperError = typeUtils.getWildcardType(null, errorType);\n      TypeMirror listOfQuerySuperError = typeUtils.getDeclaredType(list, querySuperError);\n      TypeMirror arrayOfError = typeUtils.getArrayType(errorType);\n      testErrorType(errorType);\n      testErrorType(listOfError);\n      testErrorType(listOfQueryExtendsError);\n      testErrorType(listOfQuerySuperError);\n      testErrorType(arrayOfError);\n    }\n\n    @SuppressWarnings(\"MissingFail\") // error message gets converted into assertion failure\n    private void testErrorType(TypeMirror typeWithError) {\n      try {\n        TypeEncoder.encode(typeWithError);\n        processingEnv\n            .getMessager()\n            .printMessage(Diagnostic.Kind.ERROR, \"Expected exception for type: \" + typeWithError);\n      } catch (MissingTypeException expected) {\n      }\n    }\n\n    @Override\n    public SourceVersion getSupportedSourceVersion() {\n      return SourceVersion.latestSupported();\n    }\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/TypeSimplifierTest.java",
    "content": "/*\n * Copyright 2012 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static com.google.common.truth.Truth.assertWithMessage;\n\nimport com.google.testing.compile.CompilationRule;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.TypeParameterElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.type.TypeVariable;\nimport javax.lang.model.util.ElementFilter;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.Types;\nimport org.junit.Before;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n/**\n * Tests for {@link TypeSimplifier}.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\n@RunWith(JUnit4.class)\npublic class TypeSimplifierTest {\n  @Rule public final CompilationRule compilationRule = new CompilationRule();\n\n  private Types typeUtils;\n  private Elements elementUtils;\n\n  @Before\n  public void setUp() {\n    typeUtils = compilationRule.getTypes();\n    elementUtils = compilationRule.getElements();\n  }\n\n  private static class Erasure<T> {\n    int intNo;\n    boolean booleanNo;\n    int[] intArrayNo;\n    String stringNo;\n    String[] stringArrayNo;\n\n    @SuppressWarnings(\"rawtypes\")\n    List rawListNo;\n\n    List<?> listOfQueryNo;\n    List<? extends Object> listOfQueryExtendsObjectNo;\n    Map<?, ?> mapQueryToQueryNo;\n\n    List<String> listOfStringYes;\n    List<? extends String> listOfQueryExtendsStringYes;\n    List<? super String> listOfQuerySuperStringYes;\n    List<T> listOfTypeVarYes;\n    List<? extends T> listOfQueryExtendsTypeVarYes;\n    List<? super T> listOfQuerySuperTypeVarYes;\n  }\n\n  private abstract static class Wildcards {\n    abstract <T extends V, U extends T, V> Map<? extends T, ? super U> one();\n\n    abstract <T extends V, U extends T, V> Map<? extends T, ? super U> two();\n  }\n\n  /**\n   * This test shows why we need to have TypeMirrorSet. The mirror of java.lang.Object obtained from\n   * {@link Elements#getTypeElement Elements.getTypeElement(\"java.lang.Object\")} does not compare\n   * equal to the mirror of the return type of Object.clone(), even though that is also\n   * java.lang.Object and {@link Types#isSameType} considers them the same.\n   *\n   * <p>There's no requirement that this test must pass and if it starts failing or doesn't work in\n   * another test environment then we can delete it. The specification of {@link TypeMirror#equals}\n   * explicitly says that it cannot be used for type equality, so even if this particular case stops\n   * being a problem (which means this test would fail), we would need TypeMirrorSet for complete\n   * correctness.\n   */\n  @Test\n  public void testQuirkyTypeMirrors() {\n    TypeMirror objectMirror = objectMirror();\n    TypeMirror cloneReturnTypeMirror = cloneReturnTypeMirror();\n    assertThat(objectMirror).isNotEqualTo(cloneReturnTypeMirror);\n    assertThat(typeUtils.isSameType(objectMirror, cloneReturnTypeMirror)).isTrue();\n  }\n\n  @Test\n  @SuppressWarnings(\"TypeEquals\") // We want to test the equals method invocation on TypeMirror.\n  public void testTypeMirrorSet() {\n    // Test the TypeMirrorSet methods. Resist the temptation to rewrite these in terms of\n    // Truth operations! For example, don't change assertThat(set.size()).isEqualTo(0) into\n    // assertThat(set).isEmpty(), because then we wouldn't be testing size().\n    TypeMirror objectMirror = objectMirror();\n    TypeMirror otherObjectMirror = cloneReturnTypeMirror();\n    Set<TypeMirror> set = new TypeMirrorSet();\n    assertThat(set.size()).isEqualTo(0);\n    assertThat(set.isEmpty()).isTrue();\n    boolean added = set.add(objectMirror);\n    assertThat(added).isTrue();\n    assertThat(set.size()).isEqualTo(1);\n\n    Set<TypeMirror> otherSet = typeMirrorSet(otherObjectMirror);\n    assertThat(otherSet).isEqualTo(set);\n    assertThat(set).isEqualTo(otherSet);\n    assertThat(otherSet.hashCode()).isEqualTo(set.hashCode());\n\n    assertThat(set.add(otherObjectMirror)).isFalse();\n    assertThat(set.contains(otherObjectMirror)).isTrue();\n\n    assertThat(set.contains(null)).isFalse();\n    assertThat(set.contains((Object) \"foo\")).isFalse();\n    assertThat(set.remove(null)).isFalse();\n    assertThat(set.remove((Object) \"foo\")).isFalse();\n\n    TypeElement list = typeElementOf(java.util.List.class);\n    TypeMirror listOfObjectMirror = typeUtils.getDeclaredType(list, objectMirror);\n    TypeMirror listOfOtherObjectMirror = typeUtils.getDeclaredType(list, otherObjectMirror);\n    assertThat(listOfObjectMirror.equals(listOfOtherObjectMirror)).isFalse();\n    assertThat(typeUtils.isSameType(listOfObjectMirror, listOfOtherObjectMirror)).isTrue();\n    added = set.add(listOfObjectMirror);\n    assertThat(added).isTrue();\n    assertThat(set.size()).isEqualTo(2);\n    assertThat(set.add(listOfOtherObjectMirror)).isFalse();\n    assertThat(set.contains(listOfOtherObjectMirror)).isTrue();\n\n    boolean removed = set.remove(listOfOtherObjectMirror);\n    assertThat(removed).isTrue();\n    assertThat(set.contains(listOfObjectMirror)).isFalse();\n\n    set.removeAll(otherSet);\n    assertThat(set.isEmpty()).isTrue();\n  }\n\n  @Test\n  public void testTypeMirrorSetWildcardCapture() {\n    // TODO(emcmanus): this test should really be in MoreTypesTest.\n    // This test checks the assumption made by MoreTypes that you can find the\n    // upper bounds of a TypeVariable tv like this:\n    //   TypeParameterElement tpe = (TypeParameterElement) tv.asElement();\n    //   List<? extends TypeMirror> bounds = tpe.getBounds();\n    // There was some doubt as to whether this would be true in exotic cases involving\n    // wildcard capture, but apparently it is.\n    // The methods one and two here have identical signatures:\n    //   abstract <T extends V, U extends T, V> Map<? extends T, ? super U> name();\n    // Their return types should be considered equal by TypeMirrorSet. The capture of\n    // each return type is different from the original return type, but the two captures\n    // should compare equal to each other. We also add various other types like ? super U\n    // to the set to ensure that the implied calls to the equals and hashCode visitors\n    // don't cause a ClassCastException for TypeParameterElement.\n    TypeElement wildcardsElement = typeElementOf(Wildcards.class);\n    List<? extends ExecutableElement> methods =\n        ElementFilter.methodsIn(wildcardsElement.getEnclosedElements());\n    assertThat(methods).hasSize(2);\n    ExecutableElement one = methods.get(0);\n    ExecutableElement two = methods.get(1);\n    assertThat(one.getSimpleName().toString()).isEqualTo(\"one\");\n    assertThat(two.getSimpleName().toString()).isEqualTo(\"two\");\n    TypeMirrorSet typeMirrorSet = new TypeMirrorSet();\n    assertThat(typeMirrorSet.add(one.getReturnType())).isTrue();\n    assertThat(typeMirrorSet.add(two.getReturnType())).isFalse();\n    DeclaredType captureOne = (DeclaredType) typeUtils.capture(one.getReturnType());\n    assertThat(typeMirrorSet.add(captureOne)).isTrue();\n    DeclaredType captureTwo = (DeclaredType) typeUtils.capture(two.getReturnType());\n    assertThat(typeMirrorSet.add(captureTwo)).isFalse();\n    // Reminder: captureOne is Map<?#123 extends T, ?#456 super U>\n    TypeVariable extendsT = (TypeVariable) captureOne.getTypeArguments().get(0);\n    assertThat(typeMirrorSet.add(extendsT)).isTrue();\n    assertThat(typeMirrorSet.add(extendsT.getLowerBound())).isTrue(); // NoType\n    for (TypeMirror bound : ((TypeParameterElement) extendsT.asElement()).getBounds()) {\n      assertThat(typeMirrorSet.add(bound)).isTrue();\n    }\n    TypeVariable superU = (TypeVariable) captureOne.getTypeArguments().get(1);\n    assertThat(typeMirrorSet.add(superU)).isTrue();\n    assertThat(typeMirrorSet.add(superU.getLowerBound())).isTrue();\n  }\n\n  @Test\n  public void testPackageNameOfString() {\n    assertThat(TypeSimplifier.packageNameOf(typeElementOf(java.lang.String.class)))\n        .isEqualTo(\"java.lang\");\n  }\n\n  @Test\n  public void testPackageNameOfMapEntry() {\n    assertThat(TypeSimplifier.packageNameOf(typeElementOf(java.util.Map.Entry.class)))\n        .isEqualTo(\"java.util\");\n  }\n\n  // Test TypeSimplifier.isCastingUnchecked. We do this by examining the fields of the Erasure\n  // class. A field whose name ends with Yes has a type where\n  // isCastingUnchecked should return true, and one whose name ends with No has a type where\n  // isCastingUnchecked should return false.\n  @Test\n  public void testIsCastingUnchecked() {\n    TypeElement erasureClass = typeElementOf(Erasure.class);\n    List<VariableElement> fields = ElementFilter.fieldsIn(erasureClass.getEnclosedElements());\n    assertThat(fields).isNotEmpty();\n    for (VariableElement field : fields) {\n      String fieldName = field.getSimpleName().toString();\n      boolean expectUnchecked;\n      if (fieldName.endsWith(\"Yes\")) {\n        expectUnchecked = true;\n      } else if (fieldName.endsWith(\"No\")) {\n        expectUnchecked = false;\n      } else {\n        throw new AssertionError(\"Fields in Erasure class must end with Yes or No: \" + fieldName);\n      }\n      TypeMirror fieldType = field.asType();\n      boolean actualUnchecked = TypeSimplifier.isCastingUnchecked(fieldType);\n      assertWithMessage(\"Unchecked-cast status for \" + fieldType)\n          .that(actualUnchecked)\n          .isEqualTo(expectUnchecked);\n    }\n  }\n\n  private static Set<TypeMirror> typeMirrorSet(TypeMirror... typeMirrors) {\n    Set<TypeMirror> set = new TypeMirrorSet();\n    for (TypeMirror typeMirror : typeMirrors) {\n      assertThat(set.add(typeMirror)).isTrue();\n    }\n    return set;\n  }\n\n  private TypeMirror objectMirror() {\n    return typeMirrorOf(Object.class);\n  }\n\n  private TypeMirror cloneReturnTypeMirror() {\n    TypeElement object = typeElementOf(Object.class);\n    ExecutableElement clone = null;\n    for (Element element : object.getEnclosedElements()) {\n      if (element.getSimpleName().contentEquals(\"clone\")) {\n        clone = (ExecutableElement) element;\n        break;\n      }\n    }\n    return clone.getReturnType();\n  }\n\n  private TypeElement typeElementOf(Class<?> c) {\n    return elementUtils.getTypeElement(c.getCanonicalName());\n  }\n\n  private TypeMirror typeMirrorOf(Class<?> c) {\n    return typeElementOf(c).asType();\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/TypeVariablesTest.java",
    "content": "/*\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor;\n\nimport static com.google.common.truth.Truth.assertThat;\n\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.truth.Expect;\nimport com.google.testing.compile.CompilationRule;\nimport java.util.List;\nimport java.util.Map;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.util.ElementFilter;\nimport javax.lang.model.util.Elements;\nimport javax.lang.model.util.Types;\nimport org.junit.BeforeClass;\nimport org.junit.ClassRule;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\n@RunWith(JUnit4.class)\npublic class TypeVariablesTest {\n  @ClassRule public static final CompilationRule compilationRule = new CompilationRule();\n  @Rule public final Expect expect = Expect.create();\n\n  private static Elements elementUtils;\n  private static Types typeUtils;\n\n  @BeforeClass\n  public static void setUpClass() {\n    elementUtils = compilationRule.getElements();\n    typeUtils = compilationRule.getTypes();\n  }\n\n  abstract static class Source1 {\n    abstract String getFoo();\n  }\n\n  abstract static class Target1 {}\n\n  @Test\n  public void noTypeParameters() {\n    TypeElement source1 = elementUtils.getTypeElement(Source1.class.getCanonicalName());\n    TypeElement target1 = elementUtils.getTypeElement(Target1.class.getCanonicalName());\n    List<ExecutableElement> sourceMethods = ElementFilter.methodsIn(source1.getEnclosedElements());\n    ImmutableMap<ExecutableElement, AnnotatedTypeMirror> types =\n        TypeVariables.rewriteReturnTypes(typeUtils, sourceMethods, source1, target1);\n    assertThat(types)\n        .containsExactly(\n            sourceMethods.get(0), new AnnotatedTypeMirror(sourceMethods.get(0).getReturnType()));\n  }\n\n  abstract static class Source2<T> {\n    abstract List<T> getFoo();\n  }\n\n  abstract static class Target2<T> {\n    abstract void setFoo(List<T> list);\n  }\n\n  @Test\n  public void simpleTypeParameter() {\n    TypeElement source2 = elementUtils.getTypeElement(Source2.class.getCanonicalName());\n    TypeElement target2 = elementUtils.getTypeElement(Target2.class.getCanonicalName());\n    List<ExecutableElement> sourceMethods = ElementFilter.methodsIn(source2.getEnclosedElements());\n    ImmutableMap<ExecutableElement, AnnotatedTypeMirror> types =\n        TypeVariables.rewriteReturnTypes(typeUtils, sourceMethods, source2, target2);\n    List<ExecutableElement> targetMethods = ElementFilter.methodsIn(target2.getEnclosedElements());\n    TypeMirror setFooParameter = targetMethods.get(0).getParameters().get(0).asType();\n    ExecutableElement getFoo = sourceMethods.get(0);\n    TypeMirror originalGetFooReturn = getFoo.getReturnType();\n    TypeMirror rewrittenGetFooReturn = types.get(getFoo).getType();\n    assertThat(typeUtils.isAssignable(setFooParameter, originalGetFooReturn)).isFalse();\n    assertThat(typeUtils.isAssignable(setFooParameter, rewrittenGetFooReturn)).isTrue();\n  }\n\n  abstract static class Source3<T extends Comparable<T>, U> {\n    abstract Map<T, ? extends U> getFoo();\n  }\n\n  abstract static class Target3<T extends Comparable<T>, U> {\n    abstract void setFoo(Map<T, ? extends U> list);\n  }\n\n  @Test\n  public void hairyTypeParameters() {\n    TypeElement source3 = elementUtils.getTypeElement(Source3.class.getCanonicalName());\n    TypeElement target3 = elementUtils.getTypeElement(Target3.class.getCanonicalName());\n    List<ExecutableElement> sourceMethods = ElementFilter.methodsIn(source3.getEnclosedElements());\n    ImmutableMap<ExecutableElement, AnnotatedTypeMirror> types =\n        TypeVariables.rewriteReturnTypes(typeUtils, sourceMethods, source3, target3);\n    List<ExecutableElement> targetMethods = ElementFilter.methodsIn(target3.getEnclosedElements());\n    TypeMirror setFooParameter = targetMethods.get(0).getParameters().get(0).asType();\n    ExecutableElement getFoo = sourceMethods.get(0);\n    TypeMirror originalGetFooReturn = getFoo.getReturnType();\n    TypeMirror rewrittenGetFooReturn = types.get(getFoo).getType();\n    assertThat(typeUtils.isAssignable(setFooParameter, originalGetFooReturn)).isFalse();\n    assertThat(typeUtils.isAssignable(setFooParameter, rewrittenGetFooReturn)).isTrue();\n  }\n\n  abstract static class Outer<T, U extends T> {\n    abstract Map<T, U> getFoo();\n\n    abstract List<? extends T> getBar();\n\n    abstract static class Inner<T, U extends T> {\n      abstract void setFoo(Map<T, U> foo);\n\n      abstract void setBar(List<? extends T> bar);\n    }\n  }\n\n  @Test\n  public void nestedClasses() {\n    TypeElement outer = elementUtils.getTypeElement(Outer.class.getCanonicalName());\n    TypeElement inner = elementUtils.getTypeElement(Outer.Inner.class.getCanonicalName());\n    List<ExecutableElement> outerMethods = ElementFilter.methodsIn(outer.getEnclosedElements());\n    ImmutableMap<ExecutableElement, AnnotatedTypeMirror> types =\n        TypeVariables.rewriteReturnTypes(typeUtils, outerMethods, outer, inner);\n    List<ExecutableElement> innerMethods = ElementFilter.methodsIn(inner.getEnclosedElements());\n    ExecutableElement getFoo = methodNamed(outerMethods, \"getFoo\");\n    ExecutableElement getBar = methodNamed(outerMethods, \"getBar\");\n    ExecutableElement setFoo = methodNamed(innerMethods, \"setFoo\");\n    ExecutableElement setBar = methodNamed(innerMethods, \"setBar\");\n    TypeMirror setFooParameter = setFoo.getParameters().get(0).asType();\n    TypeMirror originalGetFooReturn = getFoo.getReturnType();\n    TypeMirror rewrittenGetFooReturn = types.get(getFoo).getType();\n    assertThat(typeUtils.isAssignable(setFooParameter, originalGetFooReturn)).isFalse();\n    assertThat(typeUtils.isAssignable(setFooParameter, rewrittenGetFooReturn)).isTrue();\n    TypeMirror setBarParameter = setBar.getParameters().get(0).asType();\n    TypeMirror originalGetBarReturn = getBar.getReturnType();\n    TypeMirror rewrittenGetBarReturn = types.get(getBar).getType();\n    assertThat(typeUtils.isAssignable(setBarParameter, originalGetBarReturn)).isFalse();\n    assertThat(typeUtils.isAssignable(setBarParameter, rewrittenGetBarReturn)).isTrue();\n  }\n\n  @Test\n  public void canAssignStaticMethodResult() {\n    TypeElement immutableMap = elementUtils.getTypeElement(ImmutableMap.class.getCanonicalName());\n    TypeElement string = elementUtils.getTypeElement(String.class.getCanonicalName());\n    TypeElement integer = elementUtils.getTypeElement(Integer.class.getCanonicalName());\n    TypeElement number = elementUtils.getTypeElement(Number.class.getCanonicalName());\n    TypeMirror immutableMapStringNumber =\n        typeUtils.getDeclaredType(immutableMap, string.asType(), number.asType());\n    TypeMirror immutableMapStringInteger =\n        typeUtils.getDeclaredType(immutableMap, string.asType(), integer.asType());\n    TypeElement map = elementUtils.getTypeElement(Map.class.getCanonicalName());\n    TypeMirror erasedMap = typeUtils.erasure(map.asType());\n    // If the target type is ImmutableMap<String, Number> then we should be able to use\n    //   static <K, V> ImmutableMap<K, V> ImmutableMap.copyOf(Map<? extends K, ? extends V>)\n    // with a parameter of type ImmutableMap<String, Integer>.\n    List<ExecutableElement> immutableMapMethods =\n        ElementFilter.methodsIn(immutableMap.getEnclosedElements());\n    ExecutableElement copyOf = methodNamed(immutableMapMethods, \"copyOf\", erasedMap);\n    expect\n        .that(\n            TypeVariables.canAssignStaticMethodResult(\n                copyOf, immutableMapStringInteger, immutableMapStringNumber, typeUtils))\n        .isTrue();\n    expect\n        .that(\n            TypeVariables.canAssignStaticMethodResult(\n                copyOf, immutableMapStringNumber, immutableMapStringInteger, typeUtils))\n        .isFalse();\n  }\n\n  private static ExecutableElement methodNamed(List<ExecutableElement> methods, String name) {\n    return methods.stream().filter(m -> m.getSimpleName().contentEquals(name)).findFirst().get();\n  }\n\n  private static ExecutableElement methodNamed(\n      List<ExecutableElement> methods, String name, TypeMirror erasedParameterType) {\n    return methods.stream()\n        .filter(m -> m.getSimpleName().contentEquals(name))\n        .filter(m -> m.getParameters().size() == 1)\n        .filter(\n            m ->\n                typeUtils.isSameType(\n                    erasedParameterType, typeUtils.erasure(m.getParameters().get(0).asType())))\n        .findFirst()\n        .get();\n  }\n}\n"
  },
  {
    "path": "value/src/test/java/com/google/auto/value/processor/testclasses/RuntimePermission.java",
    "content": "/*\n * Copyright 2016 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.google.auto.value.processor.testclasses;\n\n/**\n * This class just exists to test import behaviour when referencing a class which has the same name\n * as a class in java.lang.\n *\n * @author emcmanus@google.com (Éamonn McManus)\n */\npublic class RuntimePermission {}\n"
  },
  {
    "path": "value/userguide/autobuilder.md",
    "content": "# AutoBuilder\n\n\nAutoBuilder makes it easy to create a generalized builder, with setter methods\nthat accumulate values, and a build method that calls a constructor or static\nmethod with those values as parameters. Callers don't need to know the order of\nthose parameters. Parameters can also have default values. There can be\nvalidation before the constructor or method call.\n\nIf you are familiar with [AutoValue builders](builders.md) then AutoBuilder\nshould also be familiar. Where an `@AutoValue.Builder` has setter methods\ncorresponding to the getter methods in the `@AutoValue` class, an `@AutoBuilder`\nhas setter methods corresponding to the parameters of a constructor or static\nmethod. Apart from that, the two are very similar.\n\n## Example: calling a constructor\n\nHere is a simple example:\n\n```java\n@AutoBuilder(ofClass = Person.class)\nabstract class PersonBuilder {\n  static PersonBuilder personBuilder() {\n    return new AutoBuilder_PersonBuilder();\n  }\n\n  abstract PersonBuilder setName(String name);\n  abstract PersonBuilder setId(int id);\n  abstract Person build();\n}\n```\n\nIt might be used like this:\n\n```java\nPerson p = PersonBuilder.personBuilder().setName(\"Priz\").setId(6).build();\n```\n\nThat would have the same effect as this:\n\n```java\nPerson p = new Person(\"Priz\", 6);\n```\n\nBut it doesn't require you to know what order the constructor parameters are in.\n\nHere, `setName` and `setId` are _setter methods_. Calling\n`builder.setName(\"Priz\")` records the value `\"Priz\"` for the parameter `name`,\nand likewise with `setId`.\n\nThere is also a `build()` method. Calling that method invokes the `Person`\nconstructor with the parameters that were previously set.\n\n## <a name=\"kotlin\"></a> Example: calling a Kotlin constructor\n\nKotlin has named arguments and default arguments for constructors and functions,\nwhich means there is not much need for anything like AutoBuilder there. But if\nyou are constructing an instance of a Kotlin data class from Java code,\nAutoBuilder can help.\n\nGiven this trivial Kotlin data class:\n\n```kotlin\nclass KotlinData(val level: Int, val name: String?, val id: Long = -1L)\n```\n\nYou might make a builder for it like this:\n\n```java\n@AutoBuilder(ofClass = KotlinData.class)\npublic abstract class KotlinDataBuilder {\n  public static KotlinDataBuilder kotlinDataBuilder() {\n    return new AutoBuilder_KotlinDataBuilder();\n  }\n\n  public abstract KotlinDataBuilder setLevel(int x);\n  public abstract KotlinDataBuilder setName(@Nullable String x);\n  public abstract KotlinDataBuilder setId(long x);\n  public abstract KotlinData build();\n}\n```\n\nThe Kotlin type `String?` corresponds to `@Nullable String` in the AutoBuilder\nclass, where `@Nullable` is any annotation with that name, such as\n`org.jetbrains.annotations.Nullable`.\n\nThe `id` parameter has a default value of `-1L`, which means that if `setId` is\nnot called then the `id` field of the built `KotlinData` will be `-1L`.\n\nIf you are using [kapt](https://kotlinlang.org/docs/kapt.html) then you can also\ndefine the builder in the data class itself:\n\n```kotlin\nclass KotlinData(val level: Int, val name: String?, val id: Long = -1L) {\n  @AutoBuilder // we don't need ofClass: by default it is the containing class\n  interface Builder {\n    fun setLevel(x: Int): Builder\n    fun setName(x: String?): Builder\n    fun setId(x: Long): Builder\n    fun build(): KotlinData\n  }\n\n  fun toBuilder(): Builder = AutoBuilder_KotlinData_Builder(this)\n\n  companion object {\n    @JvmStatic fun builder(): Builder = AutoBuilder_KotlinData_Builder()\n  }\n}\n```\n\nThis example uses an interface rather than an abstract class for the builder,\nbut both are possible. Java code would then construct instances like this:\n\n```java\nKotlinData k = KotlinData.builder().setLevel(23).build();\n```\n\nThe example also implements a `toBuilder()` method to get a builder that starts\nout with values from the given instance. See [below](#to_builder) for more\ndetails on that.\n\n### Required configuration to understand Kotlin classes\n\nIn order for AutoBuilder to understand Kotlin classes, you will typically need\nto add a dependency on the `org.jetbrains.kotlin:kotlin-metadata-jvm` package,\nin the same place where you depend on `com.google.auto.value:auto-value`. The\nolder `org.jetbrains.kotlinx:kotlinx-metadata-jvm` should also work.\n\n## The generated subclass\n\nLike `@AutoValue.Builder`, compiling an `@AutoBuilder` class will generate a\nconcrete subclass. In the example above, this will be `class\nAutoBuilder_PersonBuilder extends PersonBuilder`. It is common to have a static\n`builder()` method, as in the example, which calls `new AutoBuilder_...()`. That\nwill typically be the only reference to the generated class.\n\nIf the `@AutoBuilder` type is nested then the name of the generated class\nreflects that nesting. For example:\n\n```java\nclass Outer {\n  static class Inner {\n    @AutoBuilder\n    abstract static class Builder {...}\n  }\n  static Inner.Builder builder() {\n    return new AutoBuilder_Outer_Inner_Builder();\n  }\n}\n```\n\n## `@AutoBuilder` annotation parameters\n\n`@AutoBuilder` has two annotation parameters, `ofClass` and `callMethod`.\n\nIf `ofClass` is specified, then `build()` will call a constructor or static\nmethod of that class. Otherwise it will call a constructor or static method of\nthe class _containing_ the `@AutoBuilder` class.\n\nIf `callMethod` is specified, then `build()` will call a static method with that\nname. Otherwise `build()` will call a constructor.\n\nThe following examples illustrate the various possibilities. These examples use\nan interface for the `@AutoBuilder` type. You can also use an abstract class; if\nit is nested then it must be static.\n\n### Both `callMethod` and `ofClass`\n\n```java\n@AutoBuilder(callMethod = \"of\", ofClass = LocalTime.class)\ninterface LocalTimeBuilder {\n  ...\n  LocalTime build(); // calls: LocalTime.of(...)\n}\n```\n\n### Only `ofClass`\n\n```java\n@AutoBuilder(ofClass = Thread.class)\ninterface ThreadBuilder {\n  ...\n  Thread build(); // calls: new Thread(...)\n}\n```\n\n### Only `callMethod`\n\n```java\nclass Foo {\n  static String concat(String first, String middle, String last) {...}\n\n  @AutoBuilder(callMethod = \"concat\")\n  interface ConcatBuilder {\n    ...\n    String build(); // calls: Foo.concat(first, middle, last)\n  }\n}\n```\n\nNotice in this example that the static method returns `String`. The implicit\n`ofClass` is `Foo`, but the static method can return any type.\n\n### Neither `callMethod` nor `ofClass`\n\n```java\nclass Person {\n  Person(String name, int id) {...}\n\n  @AutoBuilder\n  interface Builder {\n    ...\n    Person build(); // calls: new Person(name, id)\n  }\n}\n```\n\n## The build method\n\nThe build method must have a certain return type. If it calls a constructor then\nits return type must be the type of the constructed class. If it calls a static\nmethod then its return type must be the return type of the static method.\n\nThe build method is often called `build()` but it does not have to be. The only\nrequirement is that there must be exactly one no-arg abstract method that has\nthe return type just described and that does not correspond to a parameter name.\n\nThe following example uses the name `call()` since that more accurately reflects\nwhat it does:\n\n```java\npublic class LogUtil {\n  public static void log(Level severity, String message, Object... params) {...}\n\n  @AutoBuilder(callMethod = \"log\")\n  public interface Caller {\n    Caller setSeverity(Level level);\n    Caller setMessage(String message);\n    Caller setParams(Object... params);\n    void call(); // calls: LogUtil.log(severity, message, params)\n  }\n```\n\n## <a name=\"to_builder\"></a> Making a builder from a built instance\n\nIt is not always possible to map back from the result of a constructor or method\ncall to a builder that might have produced it. But in one important case, it\n*is* possible. That's when every parameter in the constructor or method\ncorresponds to a \"getter method\" in the built type. This will always be true\nwhen building a Java record or a Kotlin data class (provided its getters are\nvisible to the builder). In this case, the generated builder class will have a\nsecond constructor that takes an object of the built type as a parameter and\nproduces a builder that starts out with values from that object. That can then\nbe used to produce a new object that may differ from the first one in just one\nor two properties. (This is very similar to AutoValue's\n[`toBuilder()`](builders-howto.md#to_builder) feature.)\n\nIf the constructor or method has a parameter `String bar` then the built type\nmust have a visible method `String bar()` or `String getBar()`. (Java records\nhave the first and Kotlin data classes have the second.) If there is a\nsimilar corresponding method for every parameter then the second constructor is\ngenerated.\n\nIf you are able to change the built type, the most convenient way to use this is\nto add a `toBuilder()` instance method that calls `new AutoBuilder_Foo(this)`.\nWe saw this in the [Kotlin example](#kotlin) earlier. Otherwise, you can have\na second static `builder` method, like this:\n\n```java\n@AutoBuilder(ofClass = Person.class)\nabstract class PersonBuilder {\n  static PersonBuilder personBuilder() {\n    return new AutoBuilder_PersonBuilder();\n  }\n  static PersonBuilder personBuilder(Person person) {\n    return new AutoBuilder_PersonBuilder(person);\n  }\n  ...\n}\n```\n\n## Overloaded constructors or methods\n\nThere might be more than one constructor or static method that matches the\n`callMethod` and `ofClass`. AutoBuilder will ignore any that are not visible to\nthe generated class, meaning private, or package-private and in a different\npackage. Of the others, it will pick the one whose parameter names match the\n`@AutoBuilder` setter methods. It is a compilation error if there is not exactly\none such method or constructor.\n\n## Generics\n\nIf the builder calls the constructor of a generic type, then it must have the\nsame type parameters as that type, as in this example:\n\n```java\nclass NumberPair<T extends Number> {\n  NumberPair(T first, T second) {...}\n\n  @AutoBuilder\n  interface Builder<T extends Number> {\n    Builder<T> setFirst(T x);\n    Builder<T> setSecond(T x);\n    NumberPair<T> build();\n  }\n}\n```\n\nIf the builder calls a static method with type parameters, then it must have the\nsame type parameters, as in this example:\n\n```java\nclass Utils {\n  static <K extends Number, V> Map<K, V> singletonNumberMap(K key, V value) {...}\n\n  @AutoBuilder(callMethod = \"singletonNumberMap\")\n  interface Builder<K extends Number, V> {\n    Builder<K, V> setKey(K x);\n    Builder<K, V> setValue(V x);\n    Map<K, V> build();\n  }\n}\n```\n\nAlthough it's unusual, a Java constructor can have its own type parameters,\nseparately from any that its containing class might have. A builder that calls a\nconstructor like that must have the type parameters of the class followed by the\ntype parameters of the constructor:\n\n```java\nclass CheckedSet<E> implements Set<E> {\n  <T extends E> CheckedSet(Class<T> type) {...}\n\n  @AutoBuilder\n  interface Builder<E, T extends E> {\n    Builder<E, T> setType(Class<T> type);\n    CheckedSet<E> build();\n  }\n}\n```\n\n## Required, optional, and nullable parameters\n\nParameters that are annotated `@Nullable` are null by default. Parameters of\ntype `Optional`, `OptionalInt`, `OptionalLong`, and `OptionalDouble` are empty\nby default. Kotlin constructor parameters with default values get those values\nby default. Every other parameter is _required_, meaning that the build method\nwill throw `IllegalStateException` if any are omitted.\n\nTo establish default values for parameters, set them in the `builder()` method\nbefore returning the builder.\n\n```java\nclass Foo {\n  Foo(String bar, @Nullable String baz, String buh) {...}\n\n  static Builder builder() {\n    return new AutoBuilder_Foo_Builder()\n        .setBar(DEFAULT_BAR);\n  }\n\n  @AutoBuilder\n  interface Builder {\n    Builder setBar(String x);\n    Builder setBaz(String x);\n    Builder setBuh(String x);\n    Foo build();\n  }\n\n  {\n     builder().build(); // IllegalStateException, buh is not set\n     builder().setBuh(\"buh\").build(); // OK, bar=DEFAULT_BAR and baz=null\n     builder().setBaz(null).setBuh(\"buh\").build(); // OK\n     builder().setBar(null); // NullPointerException, bar is not @Nullable\n  }\n}\n```\n\nTrying to set a parameter that is _not_ annotated `@Nullable` to `null` will\nproduce a `NullPointerException`.\n\n`@Nullable` here is any annotation with that name, such as\n`javax.annotation.Nullable` or\n`org.checkerframework.checker.nullness.qual.Nullable`.\n\n## Getters\n\nThe `@AutoBuilder` class or interface can also have _getter_ methods. A getter\nmethod returns the value that has been set for a certain parameter. Its return\ntype can be either the same as the parameter type, or an `Optional` wrapping\nthat type. Calling the getter before any value has been set will throw an\nexception in the first case or return an empty `Optional` in the second.\n\nIn this example, the `nickname` parameter defaults to the same value as the\n`name` parameter but can also be set to a different value:\n\n```java\npublic class Named {\n  Named(String name, String nickname) {...}\n\n  @AutoBuilder\n  public abstract static class Builder {\n    public abstract Builder setName(String x);\n    public abstract Builder setNickname(String x);\n    abstract String getName();\n    abstract Optional<String> getNickname();\n    abstract Named autoBuild();\n\n    public Named build() {\n      if (!getNickname().isPresent()) {\n        setNickname(getName());\n      }\n      return autoBuild();\n    }\n  }\n}\n```\n\nThe example illustrates having a package-private `autoBuild()` method that\nAutoBuilder implements. The public `build()` method calls it after adjusting the\nnickname if necessary.\n\nThe builder in the example is an abstract class rather than an interface. An\nabstract class allows us to distinguish between public methods for users of the\nbuilder to call, and package-private methods that the builder's own logic uses.\n\n## Building annotation instances\n\nAutoBuilder can build instances of annotation interfaces. When the annotation\nhas no elements (methods in the annotation), or only one, then AutoAnnotation is\nsimpler to use. But when there are several elements, a builder is helpful. See\n[here](howto.md#annotation) for examples of both.\n\n## Naming conventions\n\nA setter method for the parameter `foo` can be called either `setFoo` or `foo`.\nA getter method can be called either `getFoo` or `foo`, and for a `boolean`\nparameter it can also be called `isFoo`. The choice for getters and setters is\nindependent. For example your getter might be `foo()` while your setter is\n`setFoo(T)`.\n\nBy convention, the parameter name of a setter method either echoes the parameter\nbeing set:<br>\n`Builder setName(String name);`<br>\nor it is just `x`:<br>\n`Builder setName(String x);`<br>\n\nIf class `Foo` has a nested `@AutoBuilder` that builds instances of `Foo`, then\nconventionally that type is called `Builder`, and instances of it are obtained\nby calling a static `Foo.builder()` method:\n\n```java\nFoo foo1 = Foo.builder().setBar(bar).setBaz(baz).build();\nFoo.Builder fooBuilder = Foo.builder();\n```\n\nIf an `@AutoBuilder` for `Foo` is its own top-level class then that class will\ntypically be called `FooBuilder` and it will have a static `fooBuilder()` method\nthat returns an instance of `FooBuilder`. That way callers can statically import\n`FooBuilder.fooBuilder` and just write `fooBuilder()` in their code.\n\n```java\n@AutoBuilder(ofClass = Foo.class)\npublic abstract class FooBuilder {\n  public static FooBuilder fooBuilder() {\n    return new AutoBuilder_FooBuilder();\n  }\n  ...\n  public abstract Foo build();\n}\n```\n\nIf an `@AutoBuilder` is designed to call a static method that is not a factory\nmethod, the word \"call\" is better than \"build\" in the name of the type\n(`FooCaller`), the static method (`fooCaller()`), and the \"build\" method (`call()`).\n\n```java\n@AutoBuilder(callMethod = \"log\", ofClass = MyLogger.class)\npublic abstract class LogCaller {\n  public static LogCaller logCaller() {\n    return new AutoBuilder_LogCaller();\n  }\n  ...\n  public abstract void call();\n}\n\n// used as:\nlogCaller().setLevel(Level.INFO).setMessage(\"oops\").call();\n```\n\n## Other builder features\n\nThere are a number of other builder features that have not been detailed here\nbecause they are the same as for `@AutoValue.Builder`. They include:\n\n*   [Special treatment of collections](builders-howto.md#collection)\n*   [Handling of nested builders](builders-howto.md#nested_builders)\n\n## When parameter names are unavailable\n\nAutoBuilder depends on knowing the names of parameters. But parameter names are\nnot always available in Java. They _are_ available in these cases, at least:\n\n*   In code that is being compiled at the same time as the `@AutoBuilder` class\n    or interface.\n*   In _records_ (from Java 16 onwards).\n*   In the constructors of Kotlin data classes.\n*   In code that was compiled with the [`-parameters`] option.\n\nA Java compiler bug means that parameter names are not available to AutoBuilder\nwhen compiling with JDK versions before 11, in any of these cases except the\nfirst. We recommend building with a recent JDK, using the `--release` option if\nnecessary to produce code that can run on earlier versions.\n\nIf parameter names are unavailable, you always have the option of introducing a\nstatic method in the same class as the `@AutoBuilder` type, and having it call\nthe method you want. Since it is compiled at the same time, its parameter names\nare available.\n\nHere's an example of fixing a problem this way. The code here typically will not\ncompile, since parameter names of JDK methods are not available:\n\n```java\nimport java.time.LocalTime;\n\npublic class TimeUtils {\n  // Does not work, since parameter names from LocalTime.of are unavailable.\n  @AutoBuilder(callMethod = \"of\", ofClass = LocalTime.class)\n  public interface TimeBuilder {\n    TimeBuilder setHour(int x);\n    TimeBuilder setMinute(int x);\n    TimeBuilder setSecond(int x);\n    LocalTime build();\n  }\n}\n```\n\nIt will produce an error message like this:\n\n```\nerror: [AutoBuilderNoMatch] Property names do not correspond to the parameter names of any static method named \"of\":\n  public interface TimeBuilder {\n  ^\n    of(int arg0, int arg1)\n    of(int arg0, int arg1, int arg2)\n    of(int arg0, int arg1, int arg2, int arg3)\n```\n\nThe names `arg0`, `arg1`, etc are concocted by the compiler because it doesn't\nhave the real names.\n\nIntroducing a static method fixes the problem:\n\n```java\nimport java.time.LocalTime;\n\npublic class TimeUtils {\n  static LocalTime localTimeOf(int hour, int minute, int second) {\n    return LocalTime.of(hour, minute, second);\n  }\n\n  @AutoBuilder(callMethod = \"localTimeOf\")\n  public interface TimeBuilder {\n    TimeBuilder setHour(int x);\n    TimeBuilder setMinute(int x);\n    TimeBuilder setSecond(int x);\n    LocalTime build();\n  }\n}\n```\n\n[`-parameters`]: https://docs.oracle.com/en/java/javase/16/docs/specs/man/javac.html#option-parameters\n"
  },
  {
    "path": "value/userguide/builders-howto.md",
    "content": "# How do I... (Builder edition)\n\n\nThis page answers common how-to questions that may come up when using AutoValue\n**with the builder option**. You should read and understand [AutoValue with\nbuilders](builders.md) first.\n\nIf you are not using a builder, see [Introduction](index.md) and\n[How do I...](howto.md) instead.\n\n## Contents\n\nHow do I...\n\n*   ... [use (or not use) `set` **prefixes**?](#beans)\n*   ... [use different **names** besides\n    `builder()`/`Builder`/`build()`?](#build_names)\n*   ... [specify a **default** value for a property?](#default)\n*   ... [initialize a builder to the same property values as an **existing**\n    value instance](#to_builder)\n*   ... [include `with-` methods on my value class for creating slightly\n    **altered** instances?](#withers)\n*   ... [**validate** property values?](#validate)\n*   ... [**normalize** (modify) a property value at `build` time?](#normalize)\n*   ... [expose **both** a builder and a factory method?](#both)\n*   ... [handle `Optional` properties?](#optional)\n*   ... [use a **collection**-valued property?](#collection)\n    *   ... [let my builder **accumulate** values for a collection-valued\n        property (not require them all at once)?](#accumulate)\n    *   ... [accumulate values for a collection-valued property, without\n        **\"breaking the chain\"**?](#add)\n    *   ... [offer **both** accumulation and set-at-once methods for the same\n        collection-valued property?](#collection_both)\n*   ... [access nested builders while building?](#nested_builders)\n*   ... [create a \"step builder\"?](#step)\n*   ... [create a builder for something other than an `@AutoValue`?](#autobuilder)\n*   ... [use a different build method for a\n    property?](#build_method)\n\n## <a name=\"beans\"></a>... use (or not use) `set` prefixes?\n\nJust as you can choose whether to use JavaBeans-style names for property getters\n(`getFoo()` or just `foo()`) in your value class, you have the same choice for\nsetters in builders too (`setFoo(value)` or just `foo(value)`). As with getters,\nyou must use these prefixes consistently or not at all.\n\nUsing `get`/`is` prefixes for getters and using the `set` prefix for setters are\nindependent choices. For example, it is fine to use the `set` prefixes on all\nyour builder methods, but omit the `get`/`is` prefixes from all your accessors.\n\nHere is the `Animal` example using `get` prefixes but not `set` prefixes:\n\n```java\n@AutoValue\nabstract class Animal {\n  abstract String getName();\n  abstract int getNumberOfLegs();\n\n  static Builder builder() {\n    return new AutoValue_Animal.Builder();\n  }\n\n  @AutoValue.Builder\n  abstract static class Builder {\n    abstract Builder name(String value);\n    abstract Builder numberOfLegs(int value);\n    abstract Animal build();\n  }\n}\n```\n\n## <a name=\"build_names\"></a>... use different names besides `builder()`/`Builder`/`build()`?\n\nUse whichever names you like; AutoValue doesn't actually care.\n\n(We would gently recommend these names as conventional.)\n\n## <a name=\"default\"></a>... specify a default value for a property?\n\nWhat should happen when a caller does not supply a value for a property before\ncalling `build()`? If the property in question is [nullable](howto.md#nullable),\nit will simply default to `null` as you would expect. And if it is\n[Optional](#optional) it will default to an empty `Optional` as you might also\nexpect. But if it isn't either of those things (including if it is a\nprimitive-valued property, which *can't* be null), then `build()` will throw an\nunchecked exception. This includes collection properties, which must be given a\nvalue. They don't default to empty unless there is a\n[collection builder](#accumulate).\n\nBut this requirement to supply a value presents a problem, since one of the main\n*advantages* of a builder in the first place is that callers can specify only\nthe properties they care about!\n\nThe solution is to provide a default value for such properties. Fortunately this\nis easy: just set it on the newly-constructed builder instance before returning\nit from the `builder()` method.\n\nHere is the `Animal` example with the default number of legs being 4:\n\n```java\n@AutoValue\nabstract class Animal {\n  abstract String name();\n  abstract int numberOfLegs();\n\n  static Builder builder() {\n    return new AutoValue_Animal.Builder()\n        .setNumberOfLegs(4);\n  }\n\n  @AutoValue.Builder\n  abstract static class Builder {\n    abstract Builder setName(String value);\n    abstract Builder setNumberOfLegs(int value);\n    abstract Animal build();\n  }\n}\n```\n\nOccasionally you may want to supply a more complex default value, possibly\nderived from other fields and only if the property is not set explicitly. This\nis covered in the section on [normalization](#normalize).\n\n## <a name=\"to_builder\"></a>... initialize a builder to the same property values as an existing value instance\n\nSuppose your caller has an existing instance of your value class, and wants to\nchange only one or two of its properties. Of course, it's immutable, but it\nwould be convenient if they could easily get a `Builder` instance representing\nthe same property values, which they could then modify and use to create a new\nvalue instance.\n\nTo give them this ability, just add an abstract `toBuilder` method, returning\nyour abstract builder type, to your value class. AutoValue will implement it.\n\n```java\n  public abstract Builder toBuilder();\n```\n\n## <a name=\"withers\"></a>... include `with-` methods on my value class for creating slightly altered instances?\n\nThis is a somewhat common pattern among immutable classes. You can't have\nsetters, but you can have methods that act similarly to setters by returning a\nnew immutable instance that has one property changed.\n\nIf you're already using the builder option, you can add these methods by hand:\n\n```java\n@AutoValue\npublic abstract class Animal {\n  public abstract String name();\n  public abstract int numberOfLegs();\n\n  public static Builder builder() {\n    return new AutoValue_Animal.Builder();\n  }\n\n  abstract Builder toBuilder();\n\n  public final Animal withName(String name) {\n    return toBuilder().setName(name).build();\n  }\n\n  @AutoValue.Builder\n  public abstract static class Builder {\n    public abstract Builder setName(String value);\n    public abstract Builder setNumberOfLegs(int value);\n    public abstract Animal build();\n  }\n}\n```\n\nNote that it's your free choice what to make public (`toBuilder`, `withName`,\nneither, or both).\n\n## <a name=\"validate\"></a>... validate property values?\n\nValidating properties is a little less straightforward than it is in the\n[non-builder case](howto.md#validate).\n\nWhat you need to do is *split* your \"build\" method into two methods:\n\n*   the non-visible, abstract method that AutoValue implements\n*   and the visible, *concrete* method you provide, which calls the generated\n    method and performs validation.\n\nWe recommend naming these methods `autoBuild` and `build`, but any names will\nwork. It ends up looking like this:\n\n```java\n@AutoValue\npublic abstract class Animal {\n  public abstract String name();\n  public abstract int numberOfLegs();\n\n  public static Builder builder() {\n    return new AutoValue_Animal.Builder();\n  }\n\n  @AutoValue.Builder\n  public abstract static class Builder {\n    public abstract Builder setName(String value);\n    public abstract Builder setNumberOfLegs(int value);\n\n    abstract Animal autoBuild();  // not public\n\n    public final Animal build() {\n      Animal animal = autoBuild();\n      Preconditions.checkState(animal.numberOfLegs() >= 0, \"Negative legs\");\n      return animal;\n    }\n  }\n}\n```\n\n## <a name=\"normalize\"></a>... normalize (modify) a property value at `build` time?\n\nSuppose you want to convert the animal's name to lower case.\n\nYou'll need to add a *getter* to your builder, as shown:\n\n```java\n@AutoValue\npublic abstract class Animal {\n  public abstract String name();\n  public abstract int numberOfLegs();\n\n  public static Builder builder() {\n    return new AutoValue_Animal.Builder();\n  }\n\n  @AutoValue.Builder\n  public abstract static class Builder {\n    public abstract Builder setName(String value);\n    public abstract Builder setNumberOfLegs(int value);\n\n    abstract String name(); // must match method name in Animal\n\n    abstract Animal autoBuild(); // not public\n\n    public final Animal build() {\n      setName(name().toLowerCase());\n      return autoBuild();\n    }\n  }\n}\n```\n\nThe getter in your builder must have the same signature as the abstract property\naccessor method in the value class. It will return the value that has been set\non the `Builder`. If no value has been set for a\nnon-[nullable](howto.md#nullable) property, `IllegalStateException` is thrown.\n\nGetters should generally only be used within the `Builder` as shown, so they are\nnot public.\n\n<p id=\"optional-getter\">As an alternative to returning the same type as the\nproperty accessor method, the builder getter can return an Optional wrapping of\nthat type. This can be used if you want to supply a default, but only if the\nproperty has not been set. (The [usual way](#default) of supplying defaults\nmeans that the property always appears to have been set.) For example, suppose\nyou wanted the default name of your Animal to be something like \"4-legged\ncreature\", where 4 is the `numberOfLegs()` property. You might write this:\n\n```java\n@AutoValue\npublic abstract class Animal {\n  public abstract String name();\n  public abstract int numberOfLegs();\n\n  public static Builder builder() {\n    return new AutoValue_Animal.Builder();\n  }\n\n  @AutoValue.Builder\n  public abstract static class Builder {\n    public abstract Builder setName(String value);\n    public abstract Builder setNumberOfLegs(int value);\n\n    abstract Optional<String> name();\n    abstract int numberOfLegs();\n\n    abstract Animal autoBuild(); // not public\n\n    public final Animal build() {\n      if (name().isEmpty()) {\n        setName(numberOfLegs() + \"-legged creature\");\n      }\n      return autoBuild();\n    }\n  }\n}\n```\n\nNotice that this will throw `IllegalStateException` if the `numberOfLegs`\nproperty hasn't been set either.\n\nThe Optional wrapping can be any of the Optional types mentioned in the\n[section](#optional) on `Optional` properties. If your property has type `int`\nit can be wrapped as either `Optional<Integer>` or `OptionalInt`, and likewise\nfor `long` and `double`.\n\n## <a name=\"both\"></a>... expose *both* a builder *and* a factory method?\n\nIf you use the builder option, AutoValue will not generate a visible constructor\nfor the generated concrete value class. If it's important to offer your caller\nthe choice of a factory method as well as the builder, then your factory method\nimplementation will have to invoke the builder itself.\n\n## <a name=\"optional\"></a>... handle `Optional` properties?\n\nProperties of type `Optional` benefit from special treatment. If you have a\nproperty of type `Optional<String>`, say, then it will default to an empty\n`Optional` without needing to [specify](#default) a default explicitly. And,\ninstead of or as well as the normal `setFoo(Optional<String>)` method, you can\nhave `setFoo(String)`. Then `setFoo(s)` is equivalent to\n`setFoo(Optional.of(s))`. (If it is `setFoo(@Nullable String)`, then `setFoo(s)`\nis equivalent to `setFoo(Optional.ofNullable(s))`.)\n\nHere, `Optional` means either [`java.util.Optional`] from Java (Java 8 or\nlater), or [`com.google.common.base.Optional`] from Guava. Java 8 also\nintroduced related classes in `java.util` called [`OptionalInt`],\n[`OptionalLong`], and [`OptionalDouble`]. You can use those in the same way. For\nexample a property of type `OptionalInt` will default to `OptionalInt.empty()`\nand you can set it with either `setFoo(OptionalInt)` or `setFoo(int)`.\n\n```java\n@AutoValue\npublic abstract class Animal {\n  public abstract Optional<String> name();\n\n  public static Builder builder() {\n    return new AutoValue_Animal.Builder();\n  }\n\n  @AutoValue.Builder\n  public abstract static class Builder {\n    // You can have either or both of these two methods:\n    public abstract Builder setName(Optional<String> value);\n    public abstract Builder setName(String value);\n    public abstract Animal build();\n  }\n}\n```\n\n[`java.util.Optional`]: https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html\n[`com.google.common.base.Optional`]: https://guava.dev/releases/snapshot/api/docs/com/google/common/base/Optional.html\n[`OptionalDouble`]: https://docs.oracle.com/javase/8/docs/api/java/util/OptionalDouble.html\n[`OptionalInt`]: https://docs.oracle.com/javase/8/docs/api/java/util/OptionalInt.html\n[`OptionalLong`]: https://docs.oracle.com/javase/8/docs/api/java/util/OptionalLong.html\n\n## <a name=\"collection\"></a>... use a collection-valued property?\n\nValue objects should be immutable, so if a property of one is a collection then\nthat collection should be immutable too. We recommend using Guava's [immutable\ncollections] to make that explicit. AutoValue's builder support includes a few\nspecial arrangements to make this more convenient.\n\nIn the examples here we use `ImmutableSet`, but the same principles apply to all\nof Guava's immutable collection types, like `ImmutableList`,\n`ImmutableMultimap`, and so on.\n\nWe recommend using the immutable type (like `ImmutableSet<String>`) as your\nactual property type. However, it can be a pain for callers to always have to\nconstruct `ImmutableSet` instances to pass into your builder. So AutoValue\nallows your builder method to accept an argument of any type that\n`ImmutableSet.copyOf` accepts.\n\nIf our `Animal` acquires an `ImmutableSet<String>` that is the countries it\nlives in, that can be set from a `Set<String>` or a `Collection<String>` or an\n`Iterable<String>` or a `String[]` or any other compatible type. You can even\noffer multiple choices, as in this example:\n\n```java\n@AutoValue\npublic abstract class Animal {\n  public abstract String name();\n  public abstract int numberOfLegs();\n  public abstract ImmutableSet<String> countries();\n\n  public static Builder builder() {\n    return new AutoValue_Animal.Builder();\n  }\n\n  @AutoValue.Builder\n  public abstract static class Builder {\n    public abstract Builder setName(String value);\n    public abstract Builder setNumberOfLegs(int value);\n    public abstract Builder setCountries(Set<String> value);\n    public abstract Builder setCountries(String... value);\n    public abstract Animal build();\n  }\n}\n```\n\n[immutable collections]: https://github.com/google/guava/wiki/ImmutableCollectionsExplained\n\n### <a name=\"accumulate\"></a>... let my builder *accumulate* values for a collection-valued property (not require them all at once)?\n\nInstead of defining a setter for an immutable collection `foos`, you can define\na method `foosBuilder()` that returns the associated builder type for that\ncollection. In this example, we have an `ImmutableSet<String>` which can be\nbuilt using the `countriesBuilder()` method:\n\n```java\n@AutoValue\npublic abstract class Animal {\n  public abstract String name();\n  public abstract int numberOfLegs();\n  public abstract ImmutableSet<String> countries();\n\n  public static Builder builder() {\n    return new AutoValue_Animal.Builder();\n  }\n\n  @AutoValue.Builder\n  public abstract static class Builder {\n    public abstract Builder setName(String value);\n    public abstract Builder setNumberOfLegs(int value);\n    public abstract ImmutableSet.Builder<String> countriesBuilder();\n    public abstract Animal build();\n  }\n}\n```\n\nThe name of this method must be exactly the property name (`countries` here)\nfollowed by the string `Builder`. Even if the properties follow the\n`getCountries()` convention, the builder method must be `countriesBuilder()`\nand not `getCountriesBuilder()`.\n\nIt's also possible to have a method like `countriesBuilder` with a single\nargument, provided that the `Builder` class has a public constructor or a\nstatic `builder` method, with one parameter that the argument can be assigned\nto. For example, if `countries()` were an `ImmutableSortedSet<String>` and you\nwanted to supply a `Comparator` to `ImmutableSortedSet.Builder`, you could\nwrite:\n\n```java\n    public abstract ImmutableSortedSet.Builder<String>\n        countriesBuilder(Comparator<String> comparator);\n```\n\nThat works because `ImmutableSortedSet.Builder` has a constructor that\naccepts a `Comparator` parameter.\n\nYou may notice a small problem with these examples: the caller can no longer\ncreate their instance in a single chained statement:\n\n```java\n  // This DOES NOT work!\n  Animal dog = Animal.builder()\n      .setName(\"dog\")\n      .setNumberOfLegs(4)\n      .countriesBuilder()\n          .add(\"Guam\")\n          .add(\"Laos\")\n      .build();\n```\n\nInstead they are forced to hold the builder itself in a temporary variable:\n\n```java\n  // This DOES work... but we have to \"break the chain\"!\n  Animal.Builder builder = Animal.builder()\n      .setName(\"dog\")\n      .setNumberOfLegs(4);\n  builder.countriesBuilder()\n      .add(\"Guam\")\n      .add(\"Laos\");\n  Animal dog = builder.build();\n```\n\nOne solution for this problem is just below.\n\n### <a name=\"add\"></a>... accumulate values for a collection-valued property, without \"breaking the chain\"?\n\nAnother option is to keep `countriesBuilder()` itself non-public, and only use\nit to implement a public `addCountry` method:\n\n```java\n@AutoValue\npublic abstract class Animal {\n  public abstract String name();\n  public abstract int numberOfLegs();\n  public abstract ImmutableSet<String> countries();\n\n  public static Builder builder() {\n    return new AutoValue_Animal.Builder();\n  }\n\n  @AutoValue.Builder\n  public abstract static class Builder {\n    public abstract Builder setName(String value);\n    public abstract Builder setNumberOfLegs(int value);\n\n    abstract ImmutableSet.Builder<String> countriesBuilder();\n    public final Builder addCountry(String value) {\n      countriesBuilder().add(value);\n      return this;\n    }\n\n    public abstract Animal build();\n  }\n}\n```\n\nNow the caller can do this:\n\n```java\n  // This DOES work!\n  Animal dog = Animal.builder()\n      .setName(\"dog\")\n      .setNumberOfLegs(4)\n      .addCountry(\"Guam\")\n      .addCountry(\"Laos\") // however many times needed\n      .build();\n```\n\n### <a name=\"collection_both\"></a>... offer both accumulation and set-at-once methods for the same collection-valued property?\n\nYes, you can provide both methods, letting your caller choose the style they\nprefer.\n\nThe same caller can mix the two styles only in limited ways; once `foosBuilder`\nhas been called, any subsequent call to `setFoos` will throw an unchecked\nexception. On the other hand, calling `setFoos` first is okay; a later call to\n`foosBuilder` will return a builder already populated with the\npreviously-supplied elements.\n\n## <a name=\"nested_builders\"></a>... access nested builders while building?\n\nOften a property of an `@AutoValue` class is itself an immutable class,\nperhaps another `@AutoValue`. In such cases your builder can expose a builder\nfor that nested class. This is very similar to exposing a builder for a\ncollection property, as described [earlier](#accumulate).\n\nSuppose the `Animal` class has a property of type `Species`:\n\n```java\n@AutoValue\npublic abstract class Animal {\n  public abstract String name();\n  public abstract Species species();\n\n  public static Builder builder() {\n    return new AutoValue_Animal.Builder();\n  }\n\n  @AutoValue.Builder\n  public abstract static class Builder {\n    public abstract Builder setName(String name);\n    public abstract Species.Builder speciesBuilder();\n    public abstract Animal build();\n  }\n}\n\n@AutoValue\npublic abstract class Species {\n  public abstract String genus();\n  public abstract String epithet();\n\n  public static Builder builder() {\n    return new AutoValue_Species.Builder();\n  }\n\n  @AutoValue.Builder\n  public abstract static class Builder {\n    public abstract Builder setGenus(String genus);\n    public abstract Builder setEpithet(String epithet);\n    public abstract Species build();\n  }\n}\n```\n\nNow you can access the builder of the nested `Species` while you are building\nthe `Animal`:\n\n```java\n  Animal.Builder catBuilder = Animal.builder()\n      .setName(\"cat\");\n  catBuilder.speciesBuilder()\n      .setGenus(\"Felis\")\n      .setEpithet(\"catus\");\n  Animal cat = catBuilder.build();\n```\n\nAlthough the nested class in the example (`Species`) is also an `@AutoValue`\nclass, it does not have to be. For example, it could be a [protobuf]. The\nrequirements are:\n\n* The nested class must have a way to make a new builder. This can be\n  `new Species.Builder()`, or `Species.builder()`, or `Species.newBuilder()`.\n\n* There must be a way to build an instance from the builder: `Species.Builder`\n  must have a method `Species build()`.\n\n* If there is a need to convert `Species` back into its builder, then `Species`\n  must have a method `Species.Builder toBuilder()`.\n\n  In the example, if `Animal` has an abstract [`toBuilder()`](#to_builder)\n  method then `Species` must also have a `toBuilder()` method. That also applies\n  if there is an abstract `setSpecies` method in addition to the\n  `speciesBuilder` method.\n\n  As an alternative to having a method `Species.Builder toBuilder()` in\n  `Species`, `Species.Builder` can have a method called `addAll` or `putAll`\n  that accepts an argument of type `Species`. This is how AutoValue handles\n  `ImmutableSet` for example. `ImmutableSet` does not have a `toBuilder()`\n  method, but `ImmutableSet.Builder` does have an `addAll` method that accepts\n  an `ImmutableSet`. So given `ImmutableSet<String> strings`, we can achieve the\n  effect of `strings.toBuilder()` by doing:\n\n  ```\n  ImmutableSet.Builder<String> builder = ImmutableSet.builder();\n  builder.addAll(strings);\n  ```\n\nThere are no requirements on the name of the builder class. Instead of\n`Species.Builder`, it could be `Species.Factory` or `SpeciesBuilder`.\n\nIf `speciesBuilder()` is never called then the final `species()` property will\nbe set as if by `speciesBuilder().build()`. In the example, that would result\nin an exception because the required properties of `Species` have not been set.\n\n## <a name=\"step\"></a>... create a \"step builder\"?\n\nA [_step builder_](http://rdafbn.blogspot.com/2012/07/step-builder-pattern_28.html)\nis a collection of builder interfaces that take you step by step through the\nsetting of each of a list of required properties. This means you can be sure at\ncompile time that all the properties are set before you build, at the expense of\nsome extra code and a bit less flexibility.\n\nHere is an example:\n\n```java\n@AutoValue\npublic abstract class Stepped {\n  public abstract String foo();\n  public abstract String bar();\n  public abstract int baz();\n\n  public static FooStep builder() {\n    return new AutoValue_Stepped.Builder();\n  }\n\n  public interface FooStep {\n    BarStep setFoo(String foo);\n  }\n\n  public interface BarStep {\n    BazStep setBar(String bar);\n  }\n\n  public interface BazStep {\n    Build setBaz(int baz);\n  }\n\n  public interface Build {\n    Stepped build();\n  }\n\n  @AutoValue.Builder\n  abstract static class Builder implements FooStep, BarStep, BazStep, Build {}\n}\n```\n\nIt might be used like this:\n\n```java\nStepped stepped = Stepped.builder().setFoo(\"foo\").setBar(\"bar\").setBaz(3).build();\n```\n\nThe idea is that the only way to build an instance of `Stepped`\nis to go through the steps imposed by the `FooStep`, `BarStep`, and\n`BazStep` interfaces to set the properties in order, with a final build step.\n\nOnce you have set the `baz` property there is nothing else to do except build,\nso you could also combine the `setBaz` and `build` methods like this:\n\n```java\n  ...\n\n  public interface BazStep {\n    Stepped setBazAndBuild(int baz);\n  }\n\n  @AutoValue.Builder\n  abstract static class Builder implements FooStep, BarStep, BazStep {\n    abstract Builder setBaz(int baz);\n    abstract Stepped build();\n\n    @Override\n    public Stepped setBazAndBuild(int baz) {\n      return setBaz(baz).build();\n    }\n  }\n```\n\n## <a name=\"autobuilder\"></a> ... create a builder for something other than an `@AutoValue`?\n\nSometimes you want to make a builder like the kind described here, but have it\nbuild something other than an `@AutoValue` class, or even call a static method.\nIn that case you can use `@AutoBuilder`. See\n[its documentation](autobuilder.md).\n\nSometimes you want to use a different build method for your property. This is\nespecially applicable for `ImmutableMap`, which has two different build methods.\n`builder.buildOrThrow()` is used as the default build method for AutoValue. You\nmight prefer to use `builder.buildKeepingLast()` instead, so if the same key is\nput more than once then the last value is retained rather than throwing an\nexception. AutoValue doesn't currently have a way to request this, but here is a\nworkaround if you need it. Let's say you have a class like this:\n\n```java\n  @AutoValue\n  public abstract class Foo {\n    public abstract ImmutableMap<Integer, String> map();\n    ...\n\n    @AutoValue.Builder\n    public abstract static class Builder {\n      public abstract ImmutableMap.Builder<Integer, String> mapBuilder();\n      public abstract Foo build();\n    }\n  }\n```\n\nInstead, you could write this:\n\n```java\n  @AutoValue\n  public abstract class Foo {\n    public abstract ImmutableMap<Integer, String> map();\n    \n    // #start\n    // Needed only if your class has toBuilder() method\n    public Builder toBuilder() {\n      Builder builder = autoToBuilder();\n      builder.mapBuilder().putAll(map());\n      return builder;\n    }\n\n    abstract Builder autoToBuilder(); // not public\n    // #end\n\n    @AutoValue.Builder\n    public abstract static class Builder {\n\n      private final ImmutableMap.Builder<Integer, String> mapBuilder = ImmutableMap.builder();\n\n      public ImmutableMap.Builder<Integer, String> mapBuilder() {\n        return mapBuilder;\n      }\n\n      abstract Builder setMap(ImmutableMap<Integer, String> map); // not public\n\n      abstract Foo autoBuild(); // not public\n\n      public Foo build() {\n        setMap(mapBuilder.buildKeepingLast());\n        return autoBuild();\n      }\n    }\n  }\n```\n\n[protobuf]: https://developers.google.com/protocol-buffers/docs/reference/java-generated#builders\n"
  },
  {
    "path": "value/userguide/builders.md",
    "content": "# AutoValue with Builders\n\n\nThe [introduction](index.md) of this User Guide covers the basic usage of\nAutoValue using a static factory method as your public creation API. But in many\ncircumstances (such as those laid out in *Effective Java, 2nd Edition* Item 2),\nyou may prefer to let your callers use a *builder* instead.\n\nFortunately, AutoValue can generate builder classes too! This page explains how.\nNote that we recommend reading and understanding the basic usage shown in the\n[introduction](index.md) first.\n\n## How to use AutoValue with Builders <a name=\"howto\"></a>\n\nAs explained in the introduction, the AutoValue concept is that **you write an\nabstract value class, and AutoValue implements it**. Builder generation works in\nthe exact same way: you also create an abstract builder class, nesting it inside\nyour abstract value class, and AutoValue generates implementations for both.\n\n### In `Animal.java` <a name=\"example_java\"></a>\n\n```java\nimport com.google.auto.value.AutoValue;\n\n@AutoValue\nabstract class Animal {\n  abstract String name();\n  abstract int numberOfLegs();\n\n  static Builder builder() {\n    // The naming here will be different if you are using a nested class\n    // e.g. `return new AutoValue_OuterClass_InnerClass.Builder();`\n    return new AutoValue_Animal.Builder();\n  }\n\n  @AutoValue.Builder\n  abstract static class Builder {\n    abstract Builder setName(String value);\n    abstract Builder setNumberOfLegs(int value);\n    abstract Animal build();\n  }\n}\n```\n\nNote that in real life, some classes and methods would presumably be public and\nhave **Javadoc**. We're leaving these off in the User Guide only to keep the\nexamples clean and short.\n\n### Usage <a name=\"usage\"></a>\n\n```java\npublic void testAnimal() {\n  Animal dog = Animal.builder().setName(\"dog\").setNumberOfLegs(4).build();\n  assertEquals(\"dog\", dog.name());\n  assertEquals(4, dog.numberOfLegs());\n\n  // You probably don't need to write assertions like these; just illustrating.\n  assertTrue(\n      Animal.builder().setName(\"dog\").setNumberOfLegs(4).build().equals(dog));\n  assertFalse(\n      Animal.builder().setName(\"cat\").setNumberOfLegs(4).build().equals(dog));\n  assertFalse(\n      Animal.builder().setName(\"dog\").setNumberOfLegs(2).build().equals(dog));\n\n  assertEquals(\"Animal{name=dog, numberOfLegs=4}\", dog.toString());\n}\n```\n\n### What does AutoValue generate? <a name=\"generated\"></a>\n\nFor the `Animal` example shown above, here is [typical code AutoValue might\ngenerate](generated-builder-example.md).\n\n## Warnings <a name=\"warnings\"></a>\n\nBe sure to put the static `builder()` method directly in your value class (e.g.,\n`Animal`) and not the nested abstract `Builder` class. That ensures that the\n`Animal` class is always initialized before `Builder`. Otherwise you may be\nexposing yourself to initialization-order problems.\n\n## <a name=\"howto\"></a>How do I...\n\n*   ... [use (or not use) `set` **prefixes**?](builders-howto.md#beans)\n*   ... [use different **names** besides\n    `builder()`/`Builder`/`build()`?](builders-howto.md#build_names)\n*   ... [specify a **default** value for a property?](builders-howto.md#default)\n*   ... [initialize a builder to the same property values as an **existing**\n    value instance](builders-howto.md#to_builder)\n*   ... [include `with-` methods on my value class for creating slightly\n    **altered** instances?](builders-howto.md#withers)\n*   ... [**validate** property values?](builders-howto.md#validate)\n*   ... [**normalize** (modify) a property value at `build`\n    time?](builders-howto.md#normalize)\n*   ... [expose **both** a builder and a factory\n    method?](builders-howto.md#both)\n*   ... [handle `Optional` properties?](builders-howto.md#optional)\n*   ... [use a **collection**-valued property?](builders-howto.md#collection)\n    *   ... [let my builder **accumulate** values for a collection-valued\n        property (not require them all at once)?](builders-howto.md#accumulate)\n    *   ... [accumulate values for a collection-valued property, without\n        **\"breaking the chain\"**?](builders-howto.md#add)\n    *   ... [offer **both** accumulation and set-at-once methods for the same\n        collection-valued property?](builders-howto.md#collection_both)\n*   ... [access nested builders while\n    building?](builders-howto.md#nested_builders)\n*   ... [create a \"step builder\"?](builders-howto.md#step)\n*   ... [create a builder for something other than an\n    `@AutoValue`?](builders-howto.md#autobuilder)\n*   ... [use a different build method for a\n    property?](builders-howto.md#build_method)\n"
  },
  {
    "path": "value/userguide/design-faq.md",
    "content": "# Design FAQ\n\n\nTODO. This page will contain various explanations of *why* AutoValue's features\nwere designed as they are.\n"
  },
  {
    "path": "value/userguide/extensions.md",
    "content": "# Extensions\n\n\nAutoValue can be extended to implement new features for classes annotated with\n`@AutoValue`.\n\n## Using extensions\n\nEach extension is a class. If that class is on the `processorpath` when you\ncompile your `@AutoValue` class, the extension can run.\n\nSome extensions are triggered by their own annotations, which you add to your\nclass; others may be triggered in other ways. Consult the extension's\ndocumentation for usage instructions.\n\n## Writing an extension\n\nTo add a feature, write a class that extends [`AutoValueExtension`], and put\nthat class on the `processorpath` along with `AutoValueProcessor`.\n\n`AutoValueExtension` uses the [`ServiceLoader`] mechanism, which means:\n\n*   Your class must be public and have a public no-argument constructor.\n*   Its fully-qualified name must appear in a file called\n    `META-INF/services/com.google.auto.value.extension.AutoValueExtension` in a\n    JAR that is on the compiler's `classpath` or `processorpath`.\n\nYou can use [AutoService] to make implementing the `ServiceLoader` pattern easy.\n\nWithout extensions, AutoValue generates a subclass of the `@AutoValue` class.\nExtensions can work by generating a chain of subclasses, each of which alters\nbehavior by overriding or implementing new methods.\n\n## TODO\n\n*   How to distribute extensions.\n*   List of known extensions.\n\n[AutoService]: https://github.com/google/auto/tree/main/service\n[`AutoValueExtension`]: https://github.com/google/auto/blob/main/value/src/main/java/com/google/auto/value/extension/AutoValueExtension.java\n[`ServiceLoader`]: http://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html\n"
  },
  {
    "path": "value/userguide/generated-builder-example.md",
    "content": "# Generated builder example\n\n\nFor the code shown in the [builder documentation](builders.md), the following is\ntypical code AutoValue might generate:\n\n```java\nimport javax.annotation.Generated;\n\n@Generated(\"com.google.auto.value.processor.AutoValueProcessor\")\nfinal class AutoValue_Animal extends Animal {\n  private final String name;\n  private final int numberOfLegs;\n\n  private AutoValue_Animal(\n      String name,\n      int numberOfLegs) {\n    this.name = name;\n    this.numberOfLegs = numberOfLegs;\n  }\n\n  @Override\n  String name() {\n    return name;\n  }\n\n  @Override\n  int numberOfLegs() {\n    return numberOfLegs;\n  }\n\n  @Override\n  public String toString() {\n    return \"Animal{\"\n        + \"name=\" + name + \", \"\n        + \"numberOfLegs=\" + numberOfLegs\n        + \"}\";\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (o instanceof Animal) {\n      Animal that = (Animal) o;\n      return (this.name.equals(that.name()))\n           && (this.numberOfLegs == that.numberOfLegs());\n    }\n    return false;\n  }\n\n  @Override\n  public int hashCode() {\n    int h = 1;\n    h *= 1000003;\n    h ^= this.name.hashCode();\n    h *= 1000003;\n    h ^= this.numberOfLegs;\n    return h;\n  }\n\n  static final class Builder extends Animal.Builder {\n    private String name;\n    private Integer numberOfLegs;\n\n    Builder() {\n    }\n\n    @Override\n    Animal.Builder setName(String name) {\n      if (name == null) {\n        throw new NullPointerException(\"Null name\");\n      }\n      this.name = name;\n      return this;\n    }\n\n    @Override\n    Animal.Builder setNumberOfLegs(int numberOfLegs) {\n      this.numberOfLegs = numberOfLegs;\n      return this;\n    }\n\n    @Override\n    Animal build() {\n      String missing = \"\";\n      if (this.name == null) {\n        missing += \" name\";\n      }\n      if (this.numberOfLegs == null) {\n        missing += \" numberOfLegs\";\n      }\n      if (!missing.isEmpty()) {\n        throw new IllegalStateException(\"Missing required properties:\" + missing);\n      }\n      return new AutoValue_Animal(\n          this.name,\n          this.numberOfLegs);\n    }\n  }\n}\n```\n"
  },
  {
    "path": "value/userguide/generated-example.md",
    "content": "# Generated example\n\n\nFor the code shown in the [introduction](index.md), the following is typical\ncode AutoValue might generate:\n\n```java\nimport javax.annotation.Generated;\n\n@Generated(\"com.google.auto.value.processor.AutoValueProcessor\")\nfinal class AutoValue_Animal extends Animal {\n  private final String name;\n  private final int numberOfLegs;\n\n  AutoValue_Animal(String name, int numberOfLegs) {\n    if (name == null) {\n      throw new NullPointerException(\"Null name\");\n    }\n    this.name = name;\n    this.numberOfLegs = numberOfLegs;\n  }\n\n  @Override\n  String name() {\n    return name;\n  }\n\n  @Override\n  int numberOfLegs() {\n    return numberOfLegs;\n  }\n\n  @Override\n  public String toString() {\n    return \"Animal{\"\n        + \"name=\" + name + \", \"\n        + \"numberOfLegs=\" + numberOfLegs + \"}\";\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o == this) {\n      return true;\n    }\n    if (o instanceof Animal) {\n      Animal that = (Animal) o;\n      return this.name.equals(that.name())\n          && this.numberOfLegs == that.numberOfLegs();\n    }\n    return false;\n  }\n\n  @Override\n  public int hashCode() {\n    int h = 1;\n    h *= 1000003;\n    h ^= this.name.hashCode();\n    h *= 1000003;\n    h ^= this.numberOfLegs;\n    return h;\n  }\n}\n```\n"
  },
  {
    "path": "value/userguide/howto.md",
    "content": "# How do I...\n\n\nThis page answers common how-to questions that may come up when using AutoValue.\nYou should read and understand the [Introduction](index.md) first.\n\nQuestions specific to usage of the **builder option** are documented separately;\nfor this, start by reading [AutoValue with builders](builders.md).\n\n## Contents\n\nHow do I...\n\n*   ... [also generate a **builder** for my value class?](#builder)\n*   ... [use AutoValue with a **nested** class?](#nested)\n*   ... [use (or not use) JavaBeans-style name **prefixes**?](#beans)\n*   ... [use **nullable** properties?](#nullable)\n*   ... [perform other **validation**?](#validate)\n*   ... [use a property of a **mutable** type?](#mutable_property)\n*   ... [use a **custom** implementation of `equals`, etc.?](#custom)\n*   ... [have AutoValue implement a concrete or default method?](#concrete)\n*   ... [have multiple **`create`** methods, or name it/them\n    differently?](#create)\n*   ... [**ignore** certain properties in `equals`, etc.?](#ignore)\n*   ... [have AutoValue also implement abstract methods from my\n    **supertypes**?](#supertypes)\n*   ... [use AutoValue with a **generic** class?](#generic)\n*   ... [make my class Java- or GWT\\-**serializable**?](#serialize)\n*   ... [use AutoValue to **implement** an **annotation** type?](#annotation)\n*   ... [also include **setter** (mutator) methods?](#setters)\n*   ... [also generate **`compareTo`**?](#compareTo)\n*   ... [use a **primitive array** for a property value?](#primitive_array)\n*   ... [use an **object array** for a property value?](#object_array)\n*   ... [have one `@AutoValue` class **extend** another?](#inherit)\n*   ... [keep my accessor methods **private**?](#private_accessors)\n*   ... [expose a **constructor**, not factory method, as my public creation\n    API?](#public_constructor)\n*   ... [use AutoValue on an **interface**, not abstract class?](#interface)\n*   ... [**memoize** (\"cache\") derived properties?](#memoize)\n*   ... [memoize the result of `hashCode` or\n    `toString`?](#memoize_hash_tostring)\n*   ... [make a class where only one of its properties is ever set?](#oneof)\n*   ... [copy annotations from a class/method to the implemented\n    class/method/field?](#copy_annotations)\n*   ... [create a **pretty string** representation?](#toprettystring)\n\n## <a name=\"builder\"></a>... also generate a builder for my value class?\n\nPlease see [AutoValue with builders](builders.md).\n\n## <a name=\"nested\"></a>... use AutoValue with a nested class?\n\nAutoValue composes the generated class name in the form\n`AutoValue_`*`Outer_Middle_Inner`*.\nAs many of these segments will be used in the generated name as required.\nOnly the simple class name will appear in `toString` output.\n\n```java\nclass Outer {\n  static class Middle {\n    @AutoValue\n    abstract static class Inner {\n      static Inner create(String foo) {\n        return new AutoValue_Outer_Middle_Inner(foo);\n      }\n      ...\n```\n\nNOTE: Nested `@AutoValue` classes must be `static`.\n\n## <a name=\"beans\"></a>... use (or not use) JavaBeans-style name prefixes?\n\nSome developers prefer to name their accessors with a `get-` or `is-` prefix,\nbut would prefer that only the \"bare\" property name be used in `toString` and\nfor the generated constructor's parameter names.\n\nAutoValue will do exactly this, but only if you are using these prefixes\n*consistently*. In that case, it infers your intended property name by first\nstripping the `get-` or `is-` prefix, then adjusting the case of what remains as\nspecified by\n[Introspector.decapitalize](http://docs.oracle.com/javase/8/docs/api/java/beans/Introspector.html#decapitalize).\n\nNote that, in keeping with the JavaBeans specification, the `is-` prefix is only\nallowed on `boolean`-returning methods. `get-` is allowed on any type of\naccessor.\n\n## <a name=\"nullable\"></a>... use nullable properties?\n\nOrdinarily the generated constructor will reject any null values. If you want to\naccept null, simply apply any annotation named `@Nullable` to the appropriate\naccessor methods. This causes AutoValue to remove the null checks and generate\nnull-friendly code for `equals`, `hashCode` and `toString`. Example:\n\n```java\n@AutoValue\npublic abstract class Foo {\n  public static Foo create(@Nullable Bar bar) {\n    return new AutoValue_Foo(bar);\n  }\n\n  @Nullable abstract Bar bar();\n}\n```\n\nThis example also shows annotating the corresponding `create` parameter with\n`@Nullable`. AutoValue does not actually require this annotation, only the one\non the accessor, but we recommended it as useful documentation to your caller.\nConversely, if `@Nullable` is only added to the parameter in `create` (or\nsimilarly the setter method of [AutoValue.Builder](builders)), but not the\ncorresponding accessor method, it won't have any effect.\n\n## <a name=\"validate\"></a>... perform other validation?\n\nNull checks are added automatically (as [above](#nullable)). For other types of\nprecondition checks or pre-processing, just add them to your factory method:\n\n```java\nstatic MyType create(String first, String second) {\n  checkArgument(!first.isEmpty());\n  return new AutoValue_MyType(first, second.trim());\n}\n```\n\n## <a name=\"mutable_property\"></a>... use a property of a mutable type?\n\nAutoValue classes are meant and expected to be immutable. But sometimes you\nwould want to take a mutable type and use it as a property. In these cases:\n\nFirst, check if the mutable type has a corresponding immutable cousin. For\nexample, the types `List<String>` and `String[]` have the immutable counterpart\n`ImmutableList<String>` in [Guava](http://github.com/google/guava). If so, use\nthe immutable type for your property, and only accept the mutable type during\nconstruction:\n\n```java\n@AutoValue\npublic abstract class ListExample {\n  public static ListExample create(String[] mutableNames) {\n    return new AutoValue_ListExample(ImmutableList.copyOf(mutableNames));\n  }\n\n  public abstract ImmutableList<String> names();\n}\n```\n\nNote: this is a perfectly sensible practice, not an ugly workaround!\n\nIf there is no suitable immutable type to use, you'll need to proceed with\ncaution. Your static factory method should pass a *clone* of the passed object\nto the generated constructor. Your accessor method should document a very loud\nwarning never to mutate the object returned.\n\n```java\n@AutoValue\npublic abstract class MutableExample {\n  public static MutableExample create(MutablePropertyType ouch) {\n    // Replace `MutablePropertyType.copyOf()` below with the right copying code for this type\n    return new AutoValue_MutableExample(MutablePropertyType.copyOf(ouch));\n  }\n\n  /**\n   * Returns the ouch associated with this object; <b>do not mutate</b> the\n   * returned object.\n   */\n  public abstract MutablePropertyType ouch();\n}\n```\n\nWarning: this is an ugly workaround, not a perfectly sensible practice! Callers\ncan trivially break the invariants of the immutable class by mutating the\naccessor's return value. An example where something can go wrong: AutoValue\nobjects can be used as keys in Maps.\n\n## <a name=\"custom\"></a>... use a custom implementation of `equals`, etc.?\n\nSimply write your custom implementation; AutoValue will notice this and will\nskip generating its own. Your hand-written logic will thus be inherited on the\nconcrete implementation class. We call this *underriding* the method.\n\nRemember when doing this that you are losing AutoValue's protections. Be careful\nto follow the basic rules of hash codes: equal objects must have equal hash\ncodes *always*, and equal hash codes should imply equal objects *almost always*.\nYou should now test your class more thoroughly, ideally using\n[`EqualsTester`](https://www.javadoc.io/doc/com.google.guava/guava-testlib/latest/com/google/common/testing/EqualsTester.html)\nfrom\n[guava-testlib](https://central.sonatype.com/artifact/com.google.guava/guava-testlib).\n\nBest practice: mark your underriding methods `final` to make it clear to future\nreaders that these methods aren't overridden by AutoValue.\n\n## <a name=\"concrete\"></a>... have AutoValue implement a concrete or default method?\n\nIf a parent class defines a concrete (non-abstract) method that you would like\nAutoValue to implement, you can *redeclare* it as abstract. This applies to\n`Object` methods like `toString()`, but also to property methods that you would\nlike to have AutoValue implement. It also applies to default methods in\ninterfaces.\n\n```java\n@AutoValue\nclass PleaseOverrideExample extends SuperclassThatDefinesToString {\n  ...\n\n  // cause AutoValue to generate this even though the superclass has it\n  @Override public abstract String toString();\n}\n```\n\n```java\n@AutoValue\nclass PleaseReimplementDefaultMethod implements InterfaceWithDefaultMethod {\n  ...\n\n  // cause AutoValue to implement this even though the interface has a default\n  // implementation\n  @Override public abstract int numberOfLegs();\n}\n```\n\n## <a name=\"create\"></a>... have multiple `create` methods, or name it/them differently?\n\nJust do it! AutoValue doesn't actually care. This\n[best practice item](practices.md#one_reference) may be relevant.\n\n## <a name=\"ignore\"></a>... ignore certain properties in `equals`, etc.?\n\nSuppose your value class has an extra field that shouldn't be included in\n`equals` or `hashCode` computations.\n\nIf this is because it is a derived value based on other properties, see [How do\nI memoize derived properties?](#memoize).\n\nOtherwise, first make certain that you really want to do this. It is often, but\nnot always, a mistake. Remember that libraries will treat two equal instances as\nabsolutely *interchangeable* with each other. Whatever information is present in\nthis extra field could essentially \"disappear\" when you aren't expecting it, for\nexample when your value is stored and retrieved from certain collections.\n\nIf you're sure, here is how to do it:\n\n```java\n@AutoValue\nabstract class IgnoreExample {\n  static IgnoreExample create(String normalProperty, String ignoredProperty) {\n    IgnoreExample ie = new AutoValue_IgnoreExample(normalProperty);\n    ie.ignoredProperty.set(ignoredProperty);\n    return ie;\n  }\n\n  abstract String normalProperty();\n\n  private final AtomicReference<String> ignoredProperty = new AtomicReference<>();\n\n  final String ignoredProperty() {\n    return ignoredProperty.get();\n  }\n}\n```\n\nNote that this means the field is also ignored by `toString`; to AutoValue the\nprivate field simply doesn't exist.\n\nNote that we use `AtomicReference<String>` to ensure that other threads will\ncorrectly see the value that was written. You could also make the field\n`volatile`, or use `synchronized` (`synchronized (ie)` around the assignment and\n`synchronized` on the `ignoredProperty()` method).\n\n## <a name=\"supertypes\"></a>... have AutoValue also implement abstract methods from my supertypes?\n\nAutoValue will recognize every abstract accessor method whether it is defined\ndirectly in your own hand-written class or in a supertype.\n\nThese abstract methods can come from more than one place, for example from an\ninterface and from the superclass. It may not then be obvious what order they\nare in, even though you need to know this order if you want to call the\ngenerated `AutoValue_Foo` constructor. You might find it clearer to use a\n[builder](builders.md) instead. But the order is deterministic: within a class\nor interface, methods are in the order they appear in the source code; methods\nin ancestors come before methods in descendants; methods in interfaces come\nbefore methods in classes; and in a class or interface that has more than one\nsuperinterface, the interfaces are in the order of their appearance in\n`implements` or `extends`.\n\n## <a name=\"generic\"></a>... use AutoValue with a generic class?\n\nThere's nothing to it: just add type parameters to your class and to your call\nto the generated constructor.\n\n## <a name=\"serialize\"></a>... make my class Java- or GWT\\-serializable?\n\nJust add `implements Serializable` or the `@GwtCompatible(serializable = true)`\nannotation (respectively) to your hand-written class; it (as well as any\n`serialVersionUID`) will be duplicated on the generated class, and you'll be\ngood to go.\n\n## <a name=\"annotation\"></a>... use AutoValue to implement an annotation type?\n\nNote: If you are writing your annotation in Kotlin, you don't need to use\n`@AutoAnnotation`, since Kotlin allows you to instantiate annotations directly.\n\nMost users should never have the need to programmatically create \"fake\"\nannotation instances. But if you do, using `@AutoValue` in the usual way will\nfail because the `Annotation.hashCode` specification is incompatible with\nAutoValue's behavior.\n\nHowever, we've got you covered anyway! Suppose this annotation definition:\n\n```java\npublic @interface Named {\n  String value();\n}\n```\n\nAll you need is this:\n\n```java\npublic class Names {\n  @AutoAnnotation public static Named named(String value) {\n    return new AutoAnnotation_Names_named(value);\n  }\n}\n```\n\nIf your annotation has several elements, you may prefer to use `@AutoBuilder`:\n\n```java\npublic @interface Named {\n  String value();\n  int priority() default 0;\n  int size() default 0;\n}\n\npublic class Names {\n  @AutoBuilder(ofClass = Named.class)\n  public interface NamedBuilder {\n    NamedBuilder value(String x);\n    NamedBuilder priority(int x);\n    NamedBuilder size(int x);\n    Named build();\n  }\n\n  public static NamedBuilder namedBuilder() {\n    return new AutoBuilder_Names_NamedBuilder();\n  }\n\n  ...\n    Named named1 = namedBuilder().value(\"O'Cruiskeen\").priority(17).size(23).build();\n    Named named2 = namedBuilder().value(\"O'Cruiskeen\").build();\n    // priority and size get their default values\n  ...\n}\n```\n\nFor more details, see the [`AutoAnnotation`\njavadoc](http://github.com/google/auto/blob/main/value/src/main/java/com/google/auto/value/AutoAnnotation.java#L24).\n\n## <a name=\"setters\"></a>... also include setter (mutator) methods?\n\nYou can't; AutoValue only generates immutable value classes.\n\nNote that giving value semantics to a mutable type is widely considered a\nquestionable practice in the first place. Equal instances of a value class are\ntreated as *interchangeable*, but they can't truly be interchangeable if one\nmight be mutated and the other not.\n\n## <a name=\"compareTo\"></a>... also generate `compareTo`?\n\nAutoValue intentionally does not provide this feature. It is better for you to\nroll your own comparison logic using the new methods added to\n[`Comparator`](https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html)\nin Java 8, or\n[`ComparisonChain`](https://guava.dev/releases/snapshot/api/docs/com/google/common/collect/ComparisonChain.html)\nfrom [Guava](http://github.com/google/guava).\n\nSince these mechanisms are easy to use, require very little code, and give you\nthe flexibility you need, there's really no way for AutoValue to improve on\nthem!\n\n## <a name=\"primitive_array\"></a>... use a primitive array for a property value?\n\nAutoValue supports this, and will generate code that acts on the *values* stored\nthe array, not the object identity of the array itself, which is (with virtual\ncertainty) what you want. Heed the warnings given above about [mutable\nproperties](#mutable_property). AutoValue will by default warn about this case,\nbecause of the mutability, but you can silence the warning with\n`@SuppressWarnings(\"mutable\")` on the accessor method.\n\n## <a name=\"object_array\"></a>... use an object array for a property value?\n\nThis is not allowed. Object arrays are very badly-behaved and unlike primitive\narrays, they can be replaced with a proper `List` implementation for very little\nadded cost.\n\nIf it's important to accept an object array at construction time, refer to the\n*first* example shown [here](#mutable_property).\n\n## <a name=\"inherit\"></a>... have one `@AutoValue` class extend another?\n\nThis ability is intentionally not supported, because there is no way to do it\ncorrectly. See *Effective Java, 2nd Edition* Item 8: \"Obey the general contract\nwhen overriding equals\".\n\n## <a name=\"private_accessors\"></a>... keep my accessor methods private?\n\nWe're sorry. This is one of the rare and unfortunate restrictions AutoValue's\napproach places on your API. Your accessor methods don't have to be *public*,\nbut they must be at least package-visible.\n\n## <a name=\"public_constructor\"></a>... expose a constructor, not factory method, as my public creation API?\n\nWe're sorry. This is one of the rare restrictions AutoValue's approach places on\nyour API. However, note that static factory methods are recommended over public\nconstructors by *Effective Java*, Item 1.\n\n## <a name=\"interface\"></a>... use AutoValue on an interface, not abstract class?\n\nAutoValue classes can certainly implement an interface, however an interface may\nnot be used in lieu of an abstract class. The only advantage of interfaces we're\naware of is that you can omit `public abstract` from the methods. That's not\nmuch. On the other hand, you would lose the immutability guarantee, and you'd\nalso invite more of the kind of bad behavior described in\n[this best-practices item](practices.md#simple). On balance, we don't think it's\nworth it.\n\n## <a name=\"memoize\"></a>... memoize (\"cache\") derived properties?\n\nSometimes your class has properties that are derived from the ones that\nAutoValue implements. You'd typically implement them with a concrete method that\nuses the other properties:\n\n```java\n@AutoValue\nabstract class Foo {\n  abstract Bar barProperty();\n\n  String derivedProperty() {\n    return someFunctionOf(barProperty());\n  }\n}\n```\n\nBut what if `someFunctionOf(Bar)` is expensive? You'd like to calculate it only\none time, then cache and reuse that value for all future calls. Normally,\nthread-safe lazy initialization involves a lot of tricky boilerplate.\n\nInstead, just write the derived-property accessor method as above, and\nannotate it with [`@Memoized`]. Then AutoValue will override that method to\nreturn a stored value after the first call:\n\n```java\n@AutoValue\nabstract class Foo {\n  abstract Bar barProperty();\n\n  @Memoized\n  String derivedProperty() {\n    return someFunctionOf(barProperty());\n  }\n}\n```\n\nThen your method will be called at most once, even if multiple threads attempt\nto access the property concurrently.\n\nThe annotated method must have the usual form of an accessor method, and may not\nbe `abstract`, `final`, or `private`.\n\nThe stored value will not be used in the implementation of `equals`, `hashCode`,\nor `toString`.\n\nIf a `@Memoized` method is also annotated with `@Nullable`, then `null` values\nwill be stored; if not, then the overriding method throws `NullPointerException`\nwhen the annotated method returns `null`.\n\n[`@Memoized`]: https://github.com/google/auto/blob/main/value/src/main/java/com/google/auto/value/extension/memoized/Memoized.java\n\n## <a name=\"memoize_hash_tostring\"></a>... memoize the result of `hashCode` or `toString`?\n\nYou can also make your class remember and reuse the result of `hashCode`,\n`toString`, or both, like this:\n\n```java\n@AutoValue\nabstract class Foo {\n  abstract Bar barProperty();\n\n  @Memoized\n  @Override\n  public abstract int hashCode();\n\n  @Memoized\n  @Override\n  public abstract String toString();\n}\n```\n\n## <a name=\"oneof\"></a>... make a class where only one of its properties is ever set?\n\nOften, the best way to do this is using inheritance. Although one\n`@AutoValue` class can't inherit from another, two `@AutoValue` classes can\ninherit from a common parent.\n\n```java\npublic abstract class StringOrInteger {\n  public abstract String representation();\n\n  public static StringOrInteger ofString(String s) {\n    return new AutoValue_StringOrInteger_StringValue(s);\n  }\n\n  public static StringOrInteger ofInteger(int i) {\n    return new AutoValue_StringOrInteger_IntegerValue(i);\n  }\n\n  @AutoValue\n  abstract static class StringValue extends StringOrInteger {\n    abstract String string();\n\n    @Override\n    public String representation() {\n      return '\"' + string() + '\"';\n    }\n  }\n\n  @AutoValue\n  abstract static class IntegerValue extends StringOrInteger {\n    abstract int integer();\n\n    @Override\n    public String representation() {\n      return Integer.toString(integer());\n    }\n  }\n}\n```\n\nSo any `StringOrInteger` instance is actually either a `StringValue` or an\n`IntegerValue`. Clients only care about the `representation()` method, so they\ndon't need to know which it is.\n\nBut if clients of your class may want to take different actions depending on\nwhich property is set, there is an alternative to `@AutoValue` called\n`@AutoOneOf`. This effectively creates a\n[*tagged union*](https://en.wikipedia.org/wiki/Tagged_union).\nHere is `StringOrInteger` written using `@AutoOneOf`, with the\n`representation()` method moved to a separate client class:\n\n```java\n@AutoOneOf(StringOrInteger.Kind.class)\npublic abstract class StringOrInteger {\n  public enum Kind {STRING, INTEGER}\n  public abstract Kind getKind();\n\n  public abstract String string();\n\n  public abstract int integer();\n\n  public static StringOrInteger ofString(String s) {\n    return AutoOneOf_StringOrInteger.string(s);\n  }\n\n  public static StringOrInteger ofInteger(int i) {\n    return AutoOneOf_StringOrInteger.integer(i);\n  }\n}\n\npublic class Client {\n  public String representation(StringOrInteger stringOrInteger) {\n    switch (stringOrInteger.getKind()) {\n      case STRING:\n        return '\"' + stringOrInteger.string() + '\"';\n      case INTEGER:\n        return Integer.toString(stringOrInteger.integer());\n    }\n    throw new AssertionError(stringOrInteger.getKind());\n  }\n}\n```\n\nSwitching on an enum like this can lead to more robust code than using\n`instanceof` checks, especially if a tool like [Error\nProne](https://errorprone.info/bugpattern/MissingCasesInEnumSwitch) can alert you\nif you add a new variant without updating all your switches. (On the other hand,\nif nothing outside your class references `getKind()`, you should consider\nwhether using inheritance might be better.)\n\nThere must be an enum such as `Kind`, though it doesn't have to be called `Kind`\nand it doesn't have to be nested inside the `@AutoOneOf` class. There must be an\nabstract method returning the enum, though it doesn't have to be called\n`getKind()`. For every value of the enum, there must be an abstract method with\nthe same name (ignoring case and underscores). An `@AutoOneOf` class called\n`Foo` will then get a generated class called `AutoOneOf_Foo` that has a static\nfactory method for each property, with the same name. In the example, the\n`STRING` value in the enum corresponds to the `string()` property and to the\n`AutoOneOf_StringOrInteger.string` factory method.\n\nProperties in an `@AutoOneOf` class can be `void` to indicate that the\ncorresponding variant has no data. In that case, the factory method for that\nvariant has no parameters:\n\n```java\n@AutoOneOf(Transform.Kind.class)\npublic abstract class Transform {\n  public enum Kind {NONE, CIRCLE_CROP, BLUR}\n  public abstract Kind getKind();\n\n  abstract void none();\n\n  abstract void circleCrop();\n\n  public abstract BlurTransformParameters blur();\n\n  public static Transform ofNone() {\n    return AutoOneOf_Transform.none();\n  }\n\n  public static Transform ofCircleCrop() {\n    return AutoOneOf_Transform.circleCrop();\n  }\n\n  public static Transform ofBlur(BlurTransformParmeters params) {\n    return AutoOneOf_Transform.blur(params);\n  }\n}\n```\n\nHere, the `NONE` and `CIRCLE_CROP` variants have no associated data but are\ndistinct from each other. The `BLUR` variant does have data. The `none()`\nand `circleCrop()` methods are package-private; they must exist to configure\n`@AutoOneOf`, but calling them is not very useful. (It does nothing if the\ninstance is of the correct variant, or throws an exception otherwise.)\n\nThe `AutoOneOf_Transform.none()` and `AutoOneOf_Transform.circleCrop()` methods\nreturn the same instance every time they are called.\n\nIf one of the `void` variants means \"none\", consider using an `Optional<Transform>` or\na `@Nullable Transform` instead of that variant.\n\nProperties in an `@AutoOneOf` class cannot be null. Instead of a\n`StringOrInteger` with a `@Nullable String`, you probably want a\n`@Nullable StringOrInteger` or an `Optional<StringOrInteger>`, or an empty\nvariant as just described.\n\n## <a name=\"copy_annotations\"></a>... copy annotations from a class/method to the implemented class/method/field?\n\n### Copying to the generated class\n\nIf you want to copy annotations from your `@AutoValue`-annotated class to the\ngenerated `AutoValue_...` implementation, annotate your class with\n[`@AutoValue.CopyAnnotations`].\n\nFor example, if `Example.java` is:\n\n```java\n@AutoValue\n@AutoValue.CopyAnnotations\n@SuppressWarnings(\"Immutable\") // justification ...\nabstract class Example {\n  // details ...\n}\n```\n\nThen `@AutoValue` will generate `AutoValue_Example.java`:\n\n```java\n@SuppressWarnings(\"Immutable\")\nfinal class AutoValue_Example extends Example {\n  // implementation ...\n}\n```\n\nApplying `@AutoValue.CopyAnnotations` to an `@AutoValue.Builder` class like\n`Foo.Builder` similarly causes annotations on that class to be copied to the\ngenerated subclass `AutoValue_Foo.Builder`.\n\n### Copying to the generated method\n\nFor historical reasons, annotations on methods of an `@AutoValue`-annotated\nclass are copied to the generated implementation class's methods. However, if\nyou want to exclude some annotations from being copied, you can use\n[`@AutoValue.CopyAnnotations`]'s `exclude` method to stop this behavior.\n\n### Copying to the generated field\n\nIf you want to copy annotations from your `@AutoValue`-annotated class's methods\nto the generated fields in the `AutoValue_...` implementation, annotate your\nmethod with [`@AutoValue.CopyAnnotations`].\n\nFor example, if `Example.java` is:\n\n```java\n@Immutable\n@AutoValue\nabstract class Example {\n  @CopyAnnotations\n  @SuppressWarnings(\"Immutable\") // justification ...\n  abstract Object getObject();\n\n  // other details ...\n}\n```\n\nThen `@AutoValue` will generate `AutoValue_Example.java`:\n\n```java\nfinal class AutoValue_Example extends Example {\n  @SuppressWarnings(\"Immutable\")\n  private final Object object;\n\n  @SuppressWarnings(\"Immutable\")\n  @Override\n  Object getObject() {\n    return object;\n  }\n\n  // other details ...\n}\n```\n\n[`@AutoValue.CopyAnnotations`]: https://www.javadoc.io/doc/com.google.auto.value/auto-value/latest/com/google/auto/value/AutoValue.CopyAnnotations.html\n\n## <a name=\"toprettystring\"></a>... create a pretty string representation?\n\nIf you have a value class with a long `toString()` representation, annotate a\nmethod with [`@ToPrettyString`] and AutoValue will generate an implementation that\nreturns a pretty String rendering of the instance. For example:\n\n```java\n@AutoValue\nabstract class Song {\n  abstract String lyrics();\n  abstract List<Artist> artists();\n\n  @ToPrettyString\n  abstract String toPrettyString();\n}\n```\n\nBelow is a sample rendering of the result of calling `toPrettyString()`.\n\n```\nSong {\n  lyrics = I'm off the deep end, watch as I dive in\n    I'll never meet the ground\n    Crash through the surface, where they can't hurt us\n    We're far from the shallow now.,\n  artists = [\n    Artist {\n      name = Lady Gaga,\n    },\n    Artist {\n      name = Bradley Cooper,\n    }\n  ],\n}\n```\n\n`@ToPrettyString` can be used on the default `toString()` to override the\ndefault AutoValue-generated `toString()` implementation, or on another\nuser-defined method.\n\n[`@ToPrettyString`]: https://github.com/google/auto/blob/main/value/src/main/java/com/google/auto/value/extension/toprettystring/ToPrettyString.java\n"
  },
  {
    "path": "value/userguide/index.md",
    "content": "# AutoValue\n\n\n*Generated immutable value classes for Java 8+* <br />\n***Éamonn McManus, Kevin Bourrillion*** <br />\n**Google, Inc.**\n\n> \"AutoValue is a great tool for eliminating the drudgery of writing mundane\n> value classes in Java. It encapsulates much of the advice in Effective Java\n> Chapter 2, and frees you to concentrate on the more interesting aspects of\n> your program. The resulting program is likely to be shorter, clearer, and\n> freer of bugs. Two thumbs up.\"\n>\n> -- *Joshua Bloch, author, Effective Java*\n\n## <a name=\"background\"></a>Background\n\n**Value classes** are extremely common in Java projects. These are classes for\nwhich you want to treat any two instances with suitably equal field values as\ninterchangeable. That's right: we're talking about those classes where you wind\nup implementing `equals`, `hashCode` and `toString` in a bloated, repetitive,\nformulaic yet error-prone fashion.\n\nWriting these methods the first time is not too bad, with the aid of a few\nhelper methods and IDE templates. But once written they continue to burden\nreviewers, editors and future readers. Their wide expanses of boilerplate\nsharply decrease the signal-to-noise ratio of your code... and they love to\nharbor hard-to-spot bugs.\n\nAutoValue provides an easier way to create immutable value classes, with a lot\nless code and less room for error, while **not restricting your freedom** to\ncode almost any aspect of your class exactly the way you want it.\n\n**Note**: If you are using Kotlin then its\n[data classes](https://kotlinlang.org/docs/data-classes.html) are usually more\nappropriate than AutoValue. Likewise, if you are using a version of Java that\nhas [records](https://docs.oracle.com/en/java/javase/17/language/records.html),\nthen those are usually more appropriate. For a detailed comparison of AutoValue\nand records, including information on how to migrate from one to the other, see\n[here](records.md).<br>\nYou can still use [AutoBuilder](autobuilder.md) to make builders for data\nclasses or records.\n\nThis page will walk you through how to use AutoValue. Looking for a little more\npersuasion? Please see [Why AutoValue?](why.md).\n\n## <a name=\"howto\"></a>How to use AutoValue\n\nThe AutoValue concept is extremely simple: **You write an abstract class, and\nAutoValue implements it.** That is all there is to it; there is literally *no*\nconfiguration.\n\n**Note:** Below, we will illustrate an AutoValue class *without* a generated\nbuilder class. If you're more interested in the builder support, continue\nreading at [AutoValue with Builders](builders.md) instead.\n\n### <a name=\"example_java\"></a>In your value class\n\nCreate your value class as an *abstract* class, with an abstract accessor method\nfor each desired property, and bearing the `@AutoValue` annotation.\n\n```java\nimport com.google.auto.value.AutoValue;\n\n@AutoValue\nabstract class Animal {\n  static Animal create(String name, int numberOfLegs) {\n    return new AutoValue_Animal(name, numberOfLegs);\n  }\n\n  abstract String name();\n  abstract int numberOfLegs();\n}\n```\n\nThe constructor parameters correspond, in order, to the abstract accessor\nmethods.\n\n**For a nested class**, see\n[\"How do I use AutoValue with a nested class\"](howto.md#nested).\n\nNote that in real life, some classes and methods would presumably be public and\nhave Javadoc. We're leaving these off in the User Guide only to keep the\nexamples short and simple.\n\n### With Maven\n\nYou will need `auto-value-annotations-${auto-value.version}.jar` in your\ncompile-time classpath, and you will need `auto-value-${auto-value.version}.jar`\nin your annotation-processor classpath.\n\nFor `auto-value-annotations`, you can write this in `pom.xml`:\n\n```xml\n<dependencies>\n  <dependency>\n    <groupId>com.google.auto.value</groupId>\n    <artifactId>auto-value-annotations</artifactId>\n    <version>${auto-value.version}</version>\n  </dependency>\n</dependencies>\n```\n\nSome AutoValue annotations have CLASS retention. This is mostly of use for\ncompile-time tools, such as AutoValue itself. If you are creating\na library, the end user rarely needs to know the original AutoValue annotations.\nIn that case, you can set the scope to `provided`, so that the user of your\nlibrary does not have `auto-value-annotations` as a transitive dependency.\n\n```xml\n<dependencies>\n  <dependency>\n    <groupId>com.google.auto.value</groupId>\n    <artifactId>auto-value-annotations</artifactId>\n    <version>${auto-value.version}</version>\n    <scope>provided</scope>\n  </dependency>\n</dependencies>\n```\n\nFor `auto-value` (the annotation processor), you can write this:\n\n```xml\n<build>\n  <plugins>\n    <plugin>\n      <artifactId>maven-compiler-plugin</artifactId>\n      <configuration>\n        <annotationProcessorPaths>\n          <path>\n            <groupId>com.google.auto.value</groupId>\n            <artifactId>auto-value</artifactId>\n            <version>${auto-value.version}</version>\n          </path>\n        </annotationProcessorPaths>\n      </configuration>\n    </plugin>\n  </plugins>\n</build>\n```\n\nPrevious versions of these instructions suggested an alternative configuration,\nwhere the `com.google.auto.value:auto-value` dependency itself was an\n`optional` dependency. We no longer recommend that configuration. (It may pull\nunnecessary classes into your runtime classpath, and it may produce\n[warnings or errors][JDK-8321319] under recent versions of Java.)\n\n### With Gradle\n\nGradle users can declare the dependencies in their `build.gradle` script:\n\n```groovy\ndependencies {\n  compileOnly         \"com.google.auto.value:auto-value-annotations:${autoValueVersion}\"\n  annotationProcessor \"com.google.auto.value:auto-value:${autoValueVersion}\"\n}\n```\n\nNote: For java-library projects, use `compileOnlyApi` (or `api` for Gradle\nversions prior to 6.7) instead of `compileOnly`. For Android projects, use `api`\ninstead of `compileOnly`. If you are using a version prior to 4.6, you must\napply an annotation processing plugin\n[as described in these instructions][tbroyer-apt].\n\n[JDK-8321319]: https://bugs.openjdk.org/browse/JDK-8321319\n[tbroyer-apt]: https://plugins.gradle.org/plugin/net.ltgt.apt\n\n### <a name=\"usage\"></a>Usage\n\nYour choice to use AutoValue is essentially *API-invisible*. This means that, to\nthe consumer of your class, your class looks and functions like any other. The\nsimple test below illustrates that behavior. Note that in real life, you would\nwrite tests that actually *do something interesting* with the object, instead of\nonly checking field values going in and out.\n\n```java\npublic void testAnimal() {\n  Animal dog = Animal.create(\"dog\", 4);\n  assertEquals(\"dog\", dog.name());\n  assertEquals(4, dog.numberOfLegs());\n\n  // You probably don't need to write assertions like these; just illustrating.\n  assertTrue(Animal.create(\"dog\", 4).equals(dog));\n  assertFalse(Animal.create(\"cat\", 4).equals(dog));\n  assertFalse(Animal.create(\"dog\", 2).equals(dog));\n\n  assertEquals(\"Animal{name=dog, numberOfLegs=4}\", dog.toString());\n}\n```\n\n### <a name=\"whats_going_on\"></a>What's going on here?\n\nAutoValue runs inside `javac` as a standard annotation processor. It reads your\nabstract class and infers what the implementation class should look like. It\ngenerates source code, in your package, of a concrete implementation class which\nextends your abstract class, having:\n\n*   package visibility (non-public)\n*   one field for each of your abstract accessor methods\n*   a constructor that sets these fields\n*   a concrete implementation of each accessor method returning the associated\n    field value\n*   an `equals` implementation that compares these values in the usual way\n*   an appropriate corresponding `hashCode`\n*   a `toString` implementation returning a useful (but unspecified) string\n    representation of the instance\n\nYour hand-written code, as shown above, delegates its factory method call to the\ngenerated constructor and voilà!\n\nFor the `Animal` example shown above, here is\n[typical code AutoValue might generate](generated-example.md).\n\nNote that *consumers* of your value class *don't need to know any of this*. They\njust invoke your provided factory method and get a well-behaved instance back.\n\n## <a name=\"warnings\"></a>Warnings\n\nBe careful that you don't accidentally pass parameters to the generated\nconstructor in the wrong order. You must ensure that **your tests are\nsufficient** to catch any field ordering problem. In most cases this should be\nthe natural outcome from testing whatever actual purpose this value class was\ncreated for! In other cases a very simple test like the one shown above is\nenough. Consider switching to use the [builder option](builders.md) to avoid\nthis problem.\n\nWe reserve the right to **change the `hashCode` implementation** at any time.\nNever persist the result of `hashCode` or use it for any other unintended\npurpose, and be careful never to depend on the order your values appear in\nunordered collections like `HashSet`.\n\n## <a name=\"why\"></a>Why should I use AutoValue?\n\nSee [Why AutoValue?](why.md).\n\n## <a name=\"versions\"></a>What Java versions does it work with?\n\nAutoValue requires that your compiler be at least Java 8.\n\n## <a name=\"more_howto\"></a>How do I...\n\nHow do I...\n\n*   ... [also generate a **builder** for my value class?](howto.md#builder)\n*   ... [use AutoValue with a **nested** class?](howto.md#nested)\n*   ... [use (or not use) JavaBeans-style name **prefixes**?](howto.md#beans)\n*   ... [use **nullable** properties?](howto.md#nullable)\n*   ... [perform other **validation**?](howto.md#validate)\n*   ... [use a property of a **mutable** type?](howto.md#mutable_property)\n*   ... [use a **custom** implementation of `equals`, etc.?](howto.md#custom)\n*   ... [have AutoValue implement a concrete or default\n    method?](howto.md#concrete)\n*   ... [have multiple **`create`** methods, or name it/them\n    differently?](howto.md#create)\n*   ... [**ignore** certain properties in `equals`, etc.?](howto.md#ignore)\n*   ... [have AutoValue also implement abstract methods from my\n    **supertypes**?](howto.md#supertypes)\n*   ... [use AutoValue with a **generic** class?](howto.md#generic)\n*   ... [make my class Java- or GWT\\-**serializable**?](howto.md#serialize)\n*   ... [use AutoValue to **implement** an **annotation**\n    type?](howto.md#annotation)\n*   ... [also include **setter** (mutator) methods?](howto.md#setters)\n*   ... [also generate **`compareTo`**?](howto.md#compareTo)\n*   ... [use a **primitive array** for a property\n    value?](howto.md#primitive_array)\n*   ... [use an **object array** for a property value?](howto.md#object_array)\n*   ... [have one `@AutoValue` class **extend** another?](howto.md#inherit)\n*   ... [keep my accessor methods **private**?](howto.md#private_accessors)\n*   ... [expose a **constructor**, not factory method, as my public creation\n    API?](howto.md#public_constructor)\n*   ... [use AutoValue on an **interface**, not abstract\n    class?](howto.md#interface)\n*   ... [**memoize** (\"cache\") derived properties?](howto.md#memoize)\n*   ... [memoize the result of `hashCode` or\n    `toString`?](howto.md#memoize_hash_tostring)\n*   ... [make a class where only one of its properties is ever\n    set?](howto.md#oneof)\n*   ... [copy annotations from a class/method to the implemented\n    class/method/field?](howto.md#copy_annotations)\n*   ... [create a **pretty string** representation?](howto.md#toprettystring)\n\n<!-- TODO(kevinb): should the above be only a selected subset? -->\n"
  },
  {
    "path": "value/userguide/performance.md",
    "content": "# Performance notes\n\n\nTODO: write a real page\n\n*   should perform like a hand-written class after HotSpot compiles it\n    (generated accessors can be inlined)\n*   what does proguard do with it\n*   hash codes are not cached\n"
  },
  {
    "path": "value/userguide/practices.md",
    "content": "# Best practices\n\n\n## <a name=\"interchangeable\"></a>\"Equals means interchangeable\"\n\nUse AutoValue when you want value semantics. Under value semantics, if `a` and\n`b` are instances of the same AutoValue class, and `a.equals(b)`, then `a` and\n`b` are considered interchangeable, and `a` can be used in place of `b`\neverywhere and vice versa. If your AutoValue use case does not satisfy these\ncontracts, then AutoValue may not be a good fit.\n\n## <a name=\"mutable_properties\"></a>Avoid mutable property types\n\nAvoid mutable types, including arrays, for your properties, especially if you\nmake your accessor methods `public`. The generated accessors don't copy the\nfield value on its way out, so you'd be exposing your internal state.\n\nNote that this doesn't mean your factory method can't *accept* mutable types as\ninput parameters. Example:\n\n```java\n@AutoValue\npublic abstract class ListExample {\n  abstract ImmutableList<String> names();\n\n  public static ListExample create(List<String> mutableNames) {\n    return new AutoValue_ListExample(ImmutableList.copyOf(mutableNames));\n  }\n}\n```\n\n## <a name=\"simple\"></a>Keep behavior simple and dependency-free\n\nYour class can (and should) contain *simple* intrinsic behavior. But it\nshouldn't require complex dependencies and it shouldn't access static state.\n\nYou should essentially *never* need an alternative implementation of your\nhand-written abstract class, whether hand-written or generated by a mocking\nframework. If your behavior has enough complexity (or dependencies) that it\nactually needs to be mocked or faked, split it into a separate type that is\n*not* a value type. Otherwise it permits an instance with \"real\" behavior and\none with \"mock/fake\" behavior to be `equals`, which does not make sense.\n\n## <a name=\"one_reference\"></a>One reference only\n\nOther code in the same package will be able to directly access the generated\nclass, but *should not*. It's best if each generated class has one and only one\nreference from your source code: the call from your static factory method to the\ngenerated constructor. If you have multiple factory methods, have them all\ndelegate to the same hand-written method, so there is still only one point of\ncontact with the generated code. This way, you have only one place to insert\nprecondition checks or other pre- or postprocessing.\n\n## <a name=\"final\"></a>Mark all concrete methods `final`\n\nConsider that other developers will try to read and understand your value class\nwhile looking only at your hand-written class, not the actual (generated)\nimplementation class. If you mark your concrete methods `final`, they won't have\nto wonder whether the generated subclass might be overriding them. This is\nespecially helpful if you are *[underriding](howto.md#custom)* `equals`,\n`hashCode` or `toString`!\n\n## <a name=\"constructor\"></a>Maybe add an explicit, inaccessible constructor\n\nThere are a few small advantages to adding a package-private, parameterless constructor to your abstract class. It prevents unwanted subclasses, and prevents an undocumented public constructor showing up in your generated API documentation. Whether these benefits are worth the extra noise in the file is a matter of your judgment.\n"
  },
  {
    "path": "value/userguide/records.md",
    "content": "# AutoValue and Java Records\n\n\nStarting with Java 16,\n[records](https://docs.oracle.com/en/java/javase/19/language/records.html) are a\nstandard feature of the language. If records are available to you, is there any\nreason to use AutoValue?\n\n## <a id=\"summary\"></a>The short answer\n\nGenerally, **use records** when you can. They have a very concise and readable\nsyntax, they produce less code, and they don't need any special configuration or\ndependency. They are obviously a better choice when your class is just an\naggregation of values, for example to allow a method to return multiple values\nor to combine values into a map key.\n\n(This was by design: the AutoValue authors were part of the\n[Project Amber](https://openjdk.org/projects/amber/) working group, where our\ngoal was to make the records feature the best AutoValue replacement it could\nbe.)\n\nIf you have existing code that has AutoValue classes, you might want to migrate\nsome or all of those classes to be records instead. In this document we will\nexplain how to do this, and in what cases you might prefer not to.\n\n## <a id=\"notyet\"></a>Can't use Java records yet?\n\nIf you're creating new AutoValue classes for Java 15 or earlier, **follow this\nadvice** to make sure your future conversion to records will be straightforward:\n\n*   Extend `Object` only (implementing interfaces is fine).\n*   Don't use JavaBeans-style prefixes: use `abstract int bar()`, not `abstract\n    int getBar()`.\n*   Don't declare any non-static fields of your own.\n*   Give the factory method and accessors the same visibility level as the\n    class.\n*   Avoid using [extensions](extensions.md).\n\nAdopting AutoValue at this time is still a good idea! There is no better way to\nmake sure your code is as ready as possible to migrate to records later.\n\n## <a id=\"whynot\"></a>Reasons to stick with AutoValue\n\nWhile records are usually better, there are some AutoValue features that have no\nsimple equivalent with records. So you might prefer not to try migrating\nAutoValue classes that use those features, and you might even sometimes make new\nAutoValue classes even if records are available to you.\n\n### Extensions\n\nAutoValue has [extensions](extensions.md). Some are built in, like the\n[`@Memoized`](https://javadoc.io/static/com.google.auto.value/auto-value-annotations/1.10/com/google/auto/value/extension/memoized/Memoized.html),\n[`@ToPrettyString`](https://javadoc.io/static/com.google.auto.value/auto-value-annotations/1.10/com/google/auto/value/extension/toprettystring/ToPrettyString.html),\nand\n[`@SerializableAutoValue`](https://javadoc.io/static/com.google.auto.value/auto-value-annotations/1.10/com/google/auto/value/extension/serializable/SerializableAutoValue.html)\nextensions. Most extensions will have no real equivalent with records.\n\n### <a id=\"staticfactory\"></a> Keeping the static factory method\n\nAutoValue has very few API-visible \"quirks\", but one is that it forces you to\nuse a static factory method as your class's creation API. A record can have this\ntoo, but it can't prevent its primary constructor from *also* being visible, and\nexposing two ways to do the same thing can be dangerous.\n\nWe think most users will be happy to switch to constructors and drop the factory\nmethods, but you might want to keep a factory method in some records. Perhaps\nfor compatibility reasons, or because you are normalizing input data to\ndifferent types, such as from `List` to `ImmutableList`. If you have several\nstatic factory methods then you may still want to keep some or all of them,\nbecause their names are more meaningful than if you replace them with secondary\nconstructors.\n\nIf you don't want users to call your constructor at all, records are not a good\nfit. You probably want to continue using AutoValue in that case.\n\n### Superclass\n\nThe superclass of a record is always `java.lang.Record`. Occasionally the\nsuperclass of an AutoValue class is something other than `Object`, for example\nwhen two AutoValue classes share a subset of their properties.\n\nYou might still be able to convert to records if you can convert these classes\ninto interfaces.\n\n### Derived properties\n\nRecords can't have instance fields (other than their properties). So it is hard\nto cache a derived property, for example. AutoValue makes this trivial with\n[`@Memoized`](https://javadoc.io/static/com.google.auto.value/auto-value-annotations/1.10/com/google/auto/value/extension/memoized/Memoized.html).\nRecords are not a good fit if you rely on this feature.\n\n### Primitive array properties\n\nAutoValue allows properties of primitive array types such as `byte[]` or `int[]`\nand it will implement `equals` and `hashCode` using the methods of\n`java.util.Arrays`. Records do not have any special treatment for primitive\narrays, so by default they will use the `equals` and `hashCode` methods of the\narrays. So two distinct arrays will never compare equal even if they have the\nsame contents.\n\nThe best way to avoid this problem is not to have properties with primitive\narray type, perhaps using alternatives such as\n[`ImmutableIntArray`](http://guava.dev/ImmutableIntArray). Alternatively you can\ndefine custom implementations of `equals` and `hashCode` as described in the\n[section](#eqhc) on that topic. But again, you might prefer to keep using\nAutoValue.\n\n(AutoValue doesn't allow properties of non-primitive array types.)\n\n## Translating an AutoValue class into a record\n\nSuppose you have existing AutoValue classes that you do want to translate into\nrecords, and the [above reasons](#whynot) not to don't apply. What does the\ntranslation look like?\n\nOne important difference is that AutoValue does not allow properties to be\n`null` unless they are marked `@Nullable`. Records require explicit null checks\nto achieve the same effect, typically with\n[`Objects.requireNonNull`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Objects.html#requireNonNull\\(T\\)).\n\nThis might also be a good time to start using a nullness-analysis tool on your\ncode; see [NullAway](https://github.com/uber/NullAway) for example.\n\nThe examples below show some before-and-after for various migration scenarios.\nFor brevity, we've mostly omitted the javadoc comments that good code should\nhave on its public classes and methods.\n\n### Basic example with only primitive properties\n\nBefore:\n\n```java\n@AutoValue\npublic abstract class Point {\n  public abstract int x();\n  public abstract int y();\n\n  public static Point of(int x, int y) {\n    return new AutoValue_Point(x, y);\n  }\n}\n```\n\nAfter:\n\n```java\npublic record Point(int x, int y) {\n  /** @deprecated Call the constructor directly. */\n  @Deprecated\n  public static Point of(int x, int y) {\n    return new Point(x, y);\n  }\n}\n```\n\nThe static factory method `of` is retained so clients of the `Point` class don't\nhave to be updated. If possible, you should migrate clients to call `new\nPoint(...)` instead. Then the record can be as simple as this:\n\n```java\npublic record Point(int x, int y) {}\n```\n\nWe've omitted the static factory methods from the other examples, but the\ngeneral approach applies: keep the method initially but deprecate it and change\nits body so it just calls the constructor; migrate the callers so they call the\nconstructor directly; delete the method. You might be able to use the\n[`InlineMe`](https://errorprone.info/docs/inlineme) mechanism from the Error\nProne project to encourage this migration:\n\n```java\npackage com.example.geometry;\n\npublic record Point(int x, int y) {\n  /** @deprecated Call the constructor directly. */\n  @Deprecated\n  @InlineMe(replacement = \"new Point(x, y)\", imports = \"com.example.geometry.Point\")\n  public static Point of(int x, int y) {\n    return new Point(x, y);\n  }\n}\n```\n\n### Non-primitive properties that are not `@Nullable`\n\nBefore:\n\n```java\n@AutoValue\npublic abstract class Person {\n  public abstract String name();\n  public abstract int id();\n\n  public static Person create(String name, int id) {\n    return new AutoValue_Person(name, id);\n  }\n}\n```\n\nAfter:\n\n```java\npublic record Person(String name, int id) {\n  public Person {\n    Objects.requireNonNull(name, \"name\");\n  }\n}\n```\n\n### Non-primitive properties that are all `@Nullable`\n\nBefore:\n\n```java\n@AutoValue\npublic abstract class Person {\n  public abstract @Nullable String name();\n  public abstract int id();\n\n  public static Person create(@Nullable String name, int id) {\n    return new AutoValue_Person(name, id);\n  }\n}\n```\n\nAfter:\n\n```java\npublic record Person(@Nullable String name, int id) {}\n```\n\n### Validation\n\nBefore:\n\n```java\n@AutoValue\npublic abstract class Person {\n  public abstract String name();\n  public abstract int id();\n\n  public static Person create(String name, int id) {\n    if (id <= 0) {\n      throw new IllegalArgumentException(\"Id must be positive: \" + id);\n    }\n    return new AutoValue_Person(name, id);\n  }\n}\n```\n\nAfter:\n\n```java\npublic record Person(String name, int id) {\n  public Person {\n    Objects.requireNonNull(name, \"name\");\n    if (id <= 0) {\n      throw new IllegalArgumentException(\"Id must be positive: \" + id);\n    }\n  }\n}\n```\n\n### Normalization\n\nWith records, you can rewrite the constructor parameters to apply normalization\nor canonicalization rules.\n\nIn this example we have two `int` values, but we don't care which order they are\nsupplied in. Therefore we have to put them in a standard order, or else `equals`\nwon't behave as expected.\n\nBefore:\n\n```java\n@AutoValue\npublic abstract class UnorderedPair {\n  public abstract int left();\n  public abstract int right();\n\n  public static UnorderedPair of(int left, int right) {\n    int min = Math.min(left, right);\n    int max = Math.max(left, right);\n    return new AutoValue_UnorderedPair(min, max);\n  }\n}\n```\n\nAfter:\n\n```java\npublic record UnorderedPair(int left, int right) {\n  public UnorderedPair {\n    int min = Math.min(left, right);\n    int max = Math.max(left, right);\n    left = min;\n    right = max;\n  }\n}\n```\n\nIf your normalization results in different types (or more or fewer separate\nfields) than the parameters, you will need to keep the static factory method. On\na more subtle note, the user of this record might be surprised that what they\npassed in as `left` doesn't always come out as `left()`; keeping the static\nfactory method would also allow the parameters to be named differently. See the\nsection on the [static factory](#staticfactory) method.\n\n### <a id=\"beans\"></a> JavaBeans prefixes (`getFoo()`)\n\nAutoValue allows you to prefix every property getter with `get`, but records\ndon't have any special treatment here. Imagine you have a class like this:\n\n```java\n@AutoValue\npublic abstract class Person {\n  public abstract String getName();\n  public abstract int getId();\n\n  public static Person create(String name, int id) {\n    return new AutoValue_Person(name, id);\n  }\n}\n```\n\nThe names of the fields in `Person`, and the names in its `toString()`, don't\nhave the `get` prefix:\n\n```\njshell> Person.create(\"Priz\", 6)\n$1 ==> Person{name=Priz, id=6}\njshell> $1.getName()\n$2 ==> Priz\njshell> List<String> showFields(Class<?> c) {\n   ...>   return Arrays.stream(c.getDeclaredFields()).map(Field::getName).toList();\n   ...> }\njshell> showFields($1.getClass())\n$3 ==> [name, id]\n```\n\nYou can translate this directly to a record if you don't mind a slightly strange\n`toString()`, and strange field names from reflection and debuggers:\n\n```java\npublic record Person(String getName, int getId) {\n  public Person {\n    Objects.requireNonNull(getName);\n  }\n}\n```\n\n```\njshell> Person.create(\"Priz\", 6)\n$1 ==> Person[getName=Priz, getId=6]\njshell> $1.getName()\n$2 ==> Priz\njshell> showFields($1.getClass())\n$3 ==> [getName, getId]\n```\n\nAlternatively, you can alias `Person.getName()` to be `Person.name()`, etc.:\n\n```java\npublic record Person(String name, int id) {\n  public Person {\n    Objects.requireNonNull(name);\n  }\n\n  public String getName() {\n    return name();\n  }\n\n  public int getId() {\n    return id();\n  }\n}\n```\n\nSo both `Person.getName()` and `Person.name()` are allowed. You might want to\ndeprecate the `get-` methods so you can eventually remove them.\n\n### Builders\n\nBuilders are still available when using records. Instead of\n`@AutoValue.Builder`, you use [`@AutoBuilder`](autobuilder.md).\n\nBefore:\n\n```java\n@AutoValue\npublic abstract class Person {\n  public abstract String name();\n  public abstract int id();\n\n  public static Builder builder() {\n    return new AutoValue_Person.Builder();\n  }\n\n  @AutoValue.Builder\n  public interface Builder {\n    Builder name(String name);\n    Builder id(int id);\n    Person build();\n  }\n}\n\nPerson p = Person.builder().name(\"Priz\").id(6).build();\n```\n\nAfter:\n\n```java\npublic record Person(String name, int id) {\n  public static Builder builder() {\n    return new AutoBuilder_Person_Builder();\n  }\n\n  @AutoBuilder\n  public interface Builder {\n    Builder name(String name);\n    Builder id(int id);\n    Person build();\n  }\n}\n\nPerson p = Person.builder().name(\"Priz\").id(6).build();\n```\n\nAs mentioned [above](#staticfactory), the primary constructor is always visible.\nSo you cannot assume that instances of your record will always be built with the\nbuilder. Any data validation should be performed in the constructor.\n\n### Custom `toString()`\n\nA record can define its own `toString()` in exactly the same way as an AutoValue\nclass.\n\n### <a id=\"eqhc\"></a> Custom `equals` and `hashCode`\n\nAs with AutoValue, it's unusual to want to change the default implementations of\nthese methods, and if you do you run the risk of making subtle mistakes. Anyway,\nthe idea is the same with both AutoValue and records.\n\nBefore:\n\n```java\n@AutoValue\npublic abstract class Person {\n  ...\n\n  @Override public boolean equals(Object o) {\n    return o instanceof Person that\n        && Ascii.equalsIgnoreCase(this.name(), that.name())\n        && this.id() == that.id();\n  }\n\n  @Override public int hashCode() {\n    return Objects.hash(Ascii.toLowerCase(name()), id());\n  }\n}\n```\n\nAfter:\n\n```java\npublic record Person(String name, int id) {\n  ...\n\n  @Override public boolean equals(Object o) {\n    return o instanceof Person that\n        && Ascii.equalsIgnoreCase(this.name, that.name)\n        && this.id == that.id;\n  }\n\n  @Override public int hashCode() {\n    return Objects.hash(Ascii.toLowerCase(name), id);\n  }\n}\n```\n\nWith records, the methods can access fields directly or use the corresponding\nmethods (`this.name` or `this.name()`).\n"
  },
  {
    "path": "value/userguide/trouble.md",
    "content": "# Troubleshooting\n\n\nTODO\n\n## `equals()` is not returning what I expect\n\nThis is usually a sign that one of your field types is not implementing `equals`\nas you expect. A typical offending class is [`JSONObject`]\n(https://developer.android.com/reference/org/json/JSONObject.html), which\ndoesn't override `Object.equals()` and thus compromises your class's `equals`\nbehavior as well.\n"
  },
  {
    "path": "value/userguide/why.md",
    "content": "# Why use AutoValue?\n\n\nIn versions of Java preceding\n[records](https://docs.oracle.com/en/java/javase/16/language/records.html),\nAutoValue is the only solution to the value class problem having all of the\nfollowing characteristics:\n\n*   **API-invisible** (callers cannot become dependent on your choice to use it)\n*   No runtime dependencies\n*   Negligible cost to performance\n*   Very few limitations on what your class can do\n*   Extralinguistic \"magic\" kept to an absolute minimum (uses only standard Java\n    platform technologies, in the manner they were intended)\n\nThis\n[slide presentation] compares AutoValue to numerous alternatives and explains\nwhy we think it is better.\n\n[slide presentation]: https://docs.google.com/presentation/d/14u_h-lMn7f1rXE1nDiLX0azS3IkgjGl5uxp5jGJ75RE/edit\n"
  }
]