├── .allstar └── binary_artifacts.yaml ├── .github └── workflows │ ├── gradle-wrapper-validation.yml │ └── testing.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── RELEASING.md ├── build.gradle ├── config └── codenarc │ └── codenarc.xml ├── examples ├── exampleKotlinDslProject │ ├── .gitignore │ ├── build.gradle.kts │ ├── ext │ │ ├── more.proto │ │ ├── test1.proto │ │ └── test2.proto │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── lib │ │ ├── protos-test.tar.gz │ │ └── protos.tar.gz │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ ├── java │ │ │ └── Foo.java │ │ └── proto │ │ │ ├── com │ │ │ └── example │ │ │ │ └── tutorial │ │ │ │ └── sample.proto │ │ │ ├── io │ │ │ └── grpc │ │ │ │ └── testing │ │ │ │ └── integration │ │ │ │ ├── empty.proto │ │ │ │ ├── messages.proto │ │ │ │ └── test.proto │ │ │ └── ws │ │ │ └── antonov │ │ │ └── protobuf │ │ │ └── test │ │ │ └── test.proto │ │ └── test │ │ ├── java │ │ └── FooTest.java │ │ └── proto │ │ └── test.proto └── exampleProject │ ├── .gitignore │ ├── README.md │ ├── build.gradle │ ├── ext │ ├── more.proto │ ├── test1.proto │ └── test2.proto │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── lib │ ├── protos-test.tar.gz │ └── protos.tar.gz │ ├── settings.gradle │ └── src │ ├── main │ ├── java │ │ └── Foo.java │ └── proto │ │ ├── com │ │ └── example │ │ │ └── tutorial │ │ │ └── sample.proto │ │ ├── io │ │ └── grpc │ │ │ └── testing │ │ │ └── integration │ │ │ ├── empty.proto │ │ │ ├── messages.proto │ │ │ └── test.proto │ │ └── ws │ │ └── antonov │ │ └── protobuf │ │ └── test │ │ └── test.proto │ └── test │ ├── java │ └── FooTest.java │ └── proto │ └── test.proto ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle ├── src ├── main │ ├── groovy │ │ └── com │ │ │ └── google │ │ │ └── protobuf │ │ │ └── gradle │ │ │ ├── ArchiveActionFacade.java │ │ │ ├── CopyActionFacade.java │ │ │ ├── ExecutableLocator.groovy │ │ │ ├── GenerateProtoTask.groovy │ │ │ ├── Preconditions.java │ │ │ ├── ProtobufExtension.groovy │ │ │ ├── ProtobufExtract.groovy │ │ │ ├── ProtobufPlugin.groovy │ │ │ ├── ToolsLocator.groovy │ │ │ ├── Utils.groovy │ │ │ ├── internal │ │ │ ├── DefaultProtoSourceSet.groovy │ │ │ └── ProjectExt.groovy │ │ │ └── tasks │ │ │ └── ProtoSourceSet.groovy │ └── kotlin │ │ └── com │ │ └── google │ │ └── protobuf │ │ └── gradle │ │ ├── ProtobufConfiguratorExts.kt │ │ └── ProtobufDependencyConfiguration.kt └── test │ └── groovy │ └── com │ └── google │ └── protobuf │ └── gradle │ ├── AndroidProjectDetectionTest.groovy │ ├── IDESupportTest.groovy │ ├── ProtobufAndroidPluginKotlinTest.groovy │ ├── ProtobufAndroidPluginTest.groovy │ ├── ProtobufJavaPluginTest.groovy │ ├── ProtobufKotlinDslCopySpecTest.groovy │ ├── ProtobufKotlinDslPluginTest.groovy │ ├── ProtobufPluginTestHelper.groovy │ └── ToolsLocatorSpec.groovy ├── testProject ├── build.gradle └── src │ ├── main │ └── java │ │ └── Foo.java │ └── test │ └── java │ └── FooTest.java ├── testProjectAndroid ├── build.gradle └── src │ ├── androidTest │ └── java │ │ └── io │ │ └── grpc │ │ └── helloworldexample │ │ └── TestLibrary.java │ ├── main │ └── java │ │ └── io │ │ └── grpc │ │ └── helloworldexample │ │ └── HelloworldActivity.java │ └── test │ └── java │ └── io │ └── grpc │ └── helloworldexample │ └── UnitTest.java ├── testProjectAndroidBare ├── build_base.gradle └── src │ └── main │ └── AndroidManifest.xml ├── testProjectAndroidBase ├── build_base.gradle ├── lib │ └── protos.jar ├── proguard-rules.pro └── src │ ├── androidTest │ └── proto │ │ └── sample.proto │ ├── main │ ├── AndroidManifest.xml │ ├── proto │ │ ├── README.md │ │ └── helloworld.proto │ └── res │ │ ├── layout │ │ └── activity_helloworld.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ └── values │ │ └── strings.xml │ └── test │ └── proto │ ├── README.md │ └── unittest.proto ├── testProjectAndroidDependentBase ├── build_base.gradle ├── lib │ └── protos.jar ├── proguard-rules.pro └── src │ ├── androidTest │ └── proto │ │ └── sample.proto │ ├── main │ ├── AndroidManifest.xml │ ├── proto │ │ └── helloworld.proto │ └── res │ │ ├── layout │ │ └── activity_helloworld.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ └── values │ │ └── strings.xml │ └── test │ └── proto │ └── unittest.proto ├── testProjectAndroidKotlin ├── build.gradle └── src │ ├── androidTest │ └── kotlin │ │ └── io │ │ └── grpc │ │ └── helloworldexample │ │ └── LibraryKotlin.kt │ ├── main │ └── kotlin │ │ └── io │ │ └── grpc │ │ └── helloworldexample │ │ └── HelloWorldActivityKotlin.kt │ └── test │ └── kotlin │ └── io │ └── grpc │ └── helloworldexample │ └── UnitTestKotlin.kt ├── testProjectAndroidKotlinDsl ├── build.gradle.kts ├── lib │ └── protos.jar ├── proguard-rules.pro └── src │ ├── androidTest │ ├── java │ │ └── io │ │ │ └── grpc │ │ │ └── helloworldexample │ │ │ ├── MoreAndroidTestHelper.java │ │ │ └── TestLibrary.java │ ├── proto │ │ └── sample.proto │ └── protocolbuffers │ │ └── moresample.proto │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── io │ │ │ └── grpc │ │ │ └── helloworldexample │ │ │ ├── HelloworldActivity.java │ │ │ └── MoreHelper.java │ ├── proto │ │ └── helloworld.proto │ ├── protocolbuffers │ │ └── more.proto │ └── res │ │ ├── layout │ │ └── activity_helloworld.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ └── values │ │ └── strings.xml │ └── test │ ├── java │ └── io │ │ └── grpc │ │ └── helloworldexample │ │ ├── MoreUnitTestHelper.java │ │ └── UnitTest.java │ ├── proto │ └── unittest.proto │ └── protocolbuffers │ └── moreunittest.proto ├── testProjectAndroidLibrary ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── proto │ └── messages.proto ├── testProjectBase ├── build_base.gradle ├── ext │ ├── ext1 │ │ └── test1.proto │ ├── more.proto │ ├── test1.proto │ └── test2.proto ├── lib │ ├── protos-test.tar.gz │ └── protos.tar.gz └── src │ ├── grpc │ └── proto │ │ └── io │ │ └── grpc │ │ └── testing │ │ └── integration │ │ ├── empty.proto │ │ ├── messages.proto │ │ └── test.proto │ ├── main │ └── proto │ │ ├── README.md │ │ ├── com │ │ └── example │ │ │ └── tutorial │ │ │ └── sample.proto │ │ └── ws │ │ └── antonov │ │ └── protobuf │ │ └── test │ │ └── test.proto │ └── test │ └── proto │ ├── README.md │ └── test.proto ├── testProjectBuildTimeProto └── build.gradle ├── testProjectConfigureJavaExecutable ├── build.gradle └── src │ └── main │ └── proto │ └── com │ └── example │ └── tutorial │ └── sample.proto ├── testProjectCustomProtoDir ├── build.gradle └── src │ ├── main │ ├── java │ │ └── Foo.java │ ├── protobuf │ │ ├── sample.proto │ │ └── test.protodevel │ ├── protocol buffers │ │ └── spaceinpath.proto │ └── protocolbuffers │ │ └── more.proto │ └── test │ ├── java │ └── FooTest.java │ └── protocolbuffers │ └── test.proto ├── testProjectDependent ├── build.gradle └── src │ ├── main │ └── proto │ │ └── dependent.proto │ └── test │ ├── java │ └── DependentTest.java │ └── proto │ └── dependent2.proto ├── testProjectDependentApp ├── build.gradle └── src │ ├── main │ └── proto │ │ └── dependent.proto │ └── test │ ├── java │ └── DependentTest.java │ └── proto │ └── dependent2.proto ├── testProjectJavaAndKotlin ├── build.gradle └── src │ └── test │ ├── java │ └── CallKotlinClass.java │ └── kotlin │ └── CallJavaClass.kt ├── testProjectJavaLibrary ├── build.gradle └── src │ ├── main │ └── java │ │ └── Foo.java │ └── test │ └── java │ └── FooTest.java ├── testProjectKotlin ├── build.gradle └── src │ ├── main │ └── kotlin │ │ └── KotlinFoo.kt │ └── test │ └── kotlin │ └── KotlinFooTest.kt ├── testProjectKotlinDslBase ├── build.gradle.kts ├── ext │ ├── more.proto │ ├── test1.proto │ └── test2.proto ├── lib │ ├── protos-test.tar.gz │ └── protos.tar.gz └── src │ ├── grpc │ └── proto │ │ └── io │ │ └── grpc │ │ └── testing │ │ └── integration │ │ ├── empty.proto │ │ ├── messages.proto │ │ └── test.proto │ ├── main │ └── proto │ │ ├── com │ │ └── example │ │ │ └── tutorial │ │ │ └── sample.proto │ │ └── ws │ │ └── antonov │ │ └── protobuf │ │ └── test │ │ └── test.proto │ └── test │ └── proto │ └── test.proto ├── testProjectKotlinDslCopySpec ├── build.gradle.kts └── src │ ├── main │ └── proto │ │ └── google │ │ └── type │ │ └── money.proto │ └── test │ └── java │ └── com │ └── myapp │ └── ExampleUnitTest.java └── testProjectLite ├── build.gradle └── src ├── main └── proto │ └── messages.proto └── test └── java └── LiteTest.java /.allstar/binary_artifacts.yaml: -------------------------------------------------------------------------------- 1 | # Ignore reason: The jars contain plain text that is used for testing 2 | ignorePaths: 3 | - testProjectAndroidBase/lib/protos.jar 4 | - testProjectAndroidDependentBase/lib/protos.jar 5 | - testProjectAndroidKotlinDsl/lib/protos.jar 6 | -------------------------------------------------------------------------------- /.github/workflows/gradle-wrapper-validation.yml: -------------------------------------------------------------------------------- 1 | name: "Validate Gradle Wrapper" 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | validation: 6 | name: "Validation" 7 | runs-on: ubuntu-latest 8 | timeout-minutes: 30 9 | steps: 10 | - uses: actions/checkout@v4 11 | - uses: gradle/actions/wrapper-validation@v3 12 | 13 | -------------------------------------------------------------------------------- /.github/workflows/testing.yml: -------------------------------------------------------------------------------- 1 | name: GitHub Actions Linux Testing 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | timeout-minutes: 30 16 | steps: 17 | - uses: actions/checkout@v4 18 | - uses: actions/setup-java@v4 19 | with: 20 | java-version: '11' 21 | distribution: 'temurin' 22 | - uses: gradle/actions/setup-gradle@v3 23 | - name: Gradle Assemble 24 | run: ./gradlew clean assemble --stacktrace 25 | 26 | test: 27 | needs: build 28 | strategy: 29 | matrix: 30 | tests: [ProtobufJavaPluginTest, ProtobufKotlinDslCopySpecTest, ProtobufKotlinDslPluginTest, ProtobufAndroidPluginTest, ProtobufAndroidPluginKotlinTest, AndroidProjectDetectionTest, IDESupportTest] 31 | fail-fast: false 32 | runs-on: ubuntu-latest 33 | timeout-minutes: 30 34 | steps: 35 | - uses: actions/checkout@v4 36 | - uses: actions/setup-java@v4 37 | with: 38 | java-version: '11' 39 | distribution: 'temurin' 40 | - uses: gradle/actions/setup-gradle@v3 41 | - name: Gradle Test 42 | run: ./gradlew test --tests ${{ matrix.tests }} --stacktrace 43 | 44 | codenarc: 45 | needs: build 46 | runs-on: ubuntu-latest 47 | timeout-minutes: 30 48 | steps: 49 | - uses: actions/checkout@v4 50 | - uses: actions/setup-java@v4 51 | with: 52 | java-version: '11' 53 | distribution: 'temurin' 54 | - uses: gradle/actions/setup-gradle@v3 55 | - name: Gradle Codenarc 56 | run: ./gradlew codenarcMain codenarcTest --continue 57 | - name: echo codenarcMain reports 58 | if: failure() 59 | run: test -f build/reports/codenarc/main.txt && cat build/reports/codenarc/main.txt 60 | - name: echo codenarcTest reports 61 | if: failure() 62 | run: test -f build/reports/codenarc/test.txt && cat build/reports/codenarc/test.txt 63 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /**/build 3 | protobuf-gradle-plugin.i* 4 | gradle.properties 5 | /.idea 6 | local.properties 7 | **/*~ 8 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Want to contribute? Great! First, read this page (including the small print at the end). 4 | 5 | ### Before you contribute 6 | Before we can use your code, you must sign the 7 | [Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual?csw=1) 8 | (CLA), which you can do online. The CLA is necessary mainly because you own the 9 | copyright to your changes, even after your contribution becomes part of our 10 | codebase, so we need your permission to use and distribute your code. We also 11 | need to be sure of various other things—for instance that you'll tell us if you 12 | know that your code infringes on other people's patents. You don't have to sign 13 | the CLA until after you've submitted your code for review and a member has 14 | approved it, but you must do it before we can put your code into our codebase. 15 | Before you start working on a larger contribution, you should get in touch with 16 | us first through the issue tracker with your idea so that we can help out and 17 | possibly guide you. Coordinating up front makes it much easier to avoid 18 | frustration later on. 19 | 20 | ### Code reviews 21 | All submissions, including submissions by project members, require review. We 22 | use Github pull requests for this purpose. 23 | 24 | ### The small print 25 | Contributions made by corporations are covered by a different agreement than 26 | the one above, the Software Grant and Corporate Contributor License Agreement. 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Original work copyright (c) 2015, Alex Antonov. All rights reserved. 2 | Modified work copyright (c) 2015, Google Inc. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | 3. Neither the name of the copyright holder nor the names of its contributors 15 | may be used to endorse or promote products derived from this software without 16 | specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /RELEASING.md: -------------------------------------------------------------------------------- 1 | # Release process 2 | We release protobuf-gradle-plugin to both Maven Central and Gradle Plugin Portal. 3 | 4 | Prerequisites 5 | -------------- 6 | 1. If you haven't deployed artifacts to Maven Central or Gradle Plugin Portal before, you need to 7 | set up your OSSRH (OSS Repository Hosting) account and Gradle Plugin Portal account. 8 | 9 | 2. Make sure your account is added to the project on Sonatype and Gradle Plugin Portal. 10 | 11 | - Sonatype: create a support ticket on [issues.sonatype.org](issues.sonatype.org) to acquire access 12 | to `com.google.protobuf:protobuf-gradle-plugin` project. 13 | 14 | - Gradle Plugin Portal: follow instructions on [this page](https://plugins.gradle.org/docs/reclaiming) 15 | to acquire permission for publishing new versions. 16 | 17 | 3. Generate and publish GnuPG key: 18 | - Run `gpg --full-generate-key` to generate the key. 19 | - Run `gpg -keyring secring.gpg --export-secretkeys > ~/.gnupg/secring.gpg` to export your key. 20 | - Run `gpg --keyserver certserver.pgp.com --send-keys ` to publish your key, where `keyId` 21 | is the last 8 characters of the long hex from `gpg --list=keys`. You may need to prefix `keyId` 22 | with `0x` notation. 23 | 24 | 4. Edit your Gradle user properties file (default location is `$USER_HOME/.gradle/gradle.properties`): 25 | - Make sure `ossrhUsername` and `ossrhPassword` are added according to your Sonatype user credentials. 26 | - Make sure `gradle.publish.key` and `gradle.publish.secret` are added according to your API key 27 | under the "API Keys" tab in your profile page of Gradle Plugin Portal. 28 | - Add your key information: 29 | ``` 30 | signing.keyId= 31 | signing.password= 32 | signing.secretKeyRingFile= 33 | ``` 34 | 35 | Releasing 36 | ---------- 37 | 1. Make release commit: 38 | - Edit `build.gradle`: 39 | - remove “-SNAPSHOT” from `version`. Assuming the version is `$RELEASE_VERSION`. 40 | - Edit `README.md`: 41 | - The “latest version” shown should be a version prior to `$RELEASE_VERSION`. Will refer it 42 | as `$PREV_VERSION`. 43 | - Replace all `$PREV_VERSION` to `$RELEASE_VERSION`. 44 | - Update Gradle and/or Java version requirement if necessary 45 | - Run `./gradlew clean build`. 46 | - Run `git commit -a -m “$RELEASE_VERSION release”`. 47 | - Run `git tag -a v$RELEASE_VERSION -m “The $RELEASE_VERSION release”`. 48 | 49 | 2. Make commit for next version: 50 | - Refer to the next version as `$NEXT_VERSION` 51 | - Edit `build.gradle`: change version from `$RELEASE_VERSION` to `$NEXT_VERSION-SNAPSHOT`. 52 | - Edit `README.md`: replace `$RELEASE_VERSION-SNAPSHOT` with `$NEXT_VERSION-SNAPSHOT`. 53 | - Run `git commit -a -m “Start $NEXT_VERSION development cycle”` 54 | 55 | 3. Publish artifacts: 56 | - Run `git checkout v$RELEASE_VERSION`. 57 | - Release on Maven Central: 58 | - Run `./gradlew publish`. 59 | - Go to the [OSSRH site](https://oss.sonatype.org), under “Staging Repositories”, close and release the 60 | artifact. 61 | - Release on Gradle Plugin Portal: 62 | - Run `./gradlew publishPlugins`. 63 | - Verify that artifacts are available on [Maven Central](https://search.maven.org/artifact/com.google.protobuf/protobuf-gradle-plugin) 64 | (may take a few minutes up to hours) and [Gradle Plugin Portal](https://plugins.gradle.org/plugin/com.google.protobuf) 65 | (should be available immediately). 66 | 67 | 4. Push commits: 68 | - Run `git push upstream master`. 69 | - Run `git push --tags upstream`. 70 | 71 | 5. Create release notes. 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /config/codenarc/codenarc.xml: -------------------------------------------------------------------------------- 1 | 29 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /examples/exampleKotlinDslProject/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .gradle 3 | build 4 | local.properties 5 | -------------------------------------------------------------------------------- /examples/exampleKotlinDslProject/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.google.protobuf.gradle.* 2 | 3 | plugins { 4 | id("java") 5 | id("idea") 6 | id("com.google.protobuf") version "0.9.4" 7 | } 8 | 9 | repositories { 10 | mavenCentral() 11 | } 12 | 13 | dependencies { 14 | implementation("com.google.protobuf:protobuf-java:3.6.1") 15 | implementation("io.grpc:grpc-stub:1.15.1") 16 | implementation("io.grpc:grpc-protobuf:1.15.1") 17 | 18 | if (JavaVersion.current().isJava9Compatible()) { 19 | // Workaround for @javax.annotation.Generated 20 | // see: https://github.com/grpc/grpc-java/issues/3633 21 | implementation("javax.annotation:javax.annotation-api:1.3.1") 22 | } 23 | 24 | // Extra proto source files besides the ones residing under 25 | // "src/main". 26 | protobuf(files("lib/protos.tar.gz")) 27 | protobuf(files("ext/")) 28 | 29 | testImplementation("junit:junit:4.12") 30 | // Extra proto source files for test besides the ones residing under 31 | // "src/test". 32 | testProtobuf(files("lib/protos-test.tar.gz")) 33 | } 34 | 35 | protobuf { 36 | protoc { 37 | // The artifact spec for the Protobuf Compiler 38 | artifact = "com.google.protobuf:protoc:3.6.1" 39 | } 40 | plugins { 41 | // Optional: an artifact spec for a protoc plugin, with "grpc" as 42 | // the identifier, which can be referred to in the "plugins" 43 | // container of the "generateProtoTasks" closure. 44 | id("grpc") { 45 | artifact = "io.grpc:protoc-gen-grpc-java:1.15.1" 46 | } 47 | } 48 | generateProtoTasks { 49 | ofSourceSet("main").forEach { 50 | it.plugins { 51 | // Apply the "grpc" plugin whose spec is defined above, without 52 | // options. Note the braces cannot be omitted, otherwise the 53 | // plugin will not be added. This is because of the implicit way 54 | // NamedDomainObjectContainer binds the methods. 55 | id("grpc") { } 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /examples/exampleKotlinDslProject/ext/more.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | message MoreMsg { 4 | string bar = 1; 5 | } 6 | 7 | message Foo { 8 | string stuff = 1; 9 | } 10 | -------------------------------------------------------------------------------- /examples/exampleKotlinDslProject/ext/test1.proto: -------------------------------------------------------------------------------- 1 | /** 2 | * Created with IntelliJ IDEA. 3 | * User: aantonov 4 | * Date: 1/17/13 5 | * Time: 3:44 PM 6 | * To change this template use File | Settings | File Templates. 7 | */ 8 | syntax = "proto3"; 9 | 10 | message Test1Msg { 11 | string bar = 1; 12 | } 13 | -------------------------------------------------------------------------------- /examples/exampleKotlinDslProject/ext/test2.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | message Test2Msg { 4 | string bar = 1; 5 | } 6 | -------------------------------------------------------------------------------- /examples/exampleKotlinDslProject/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/protobuf-gradle-plugin/0cce976ae1fcb35f29ec67d418a52b8622105c67/examples/exampleKotlinDslProject/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /examples/exampleKotlinDslProject/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /examples/exampleKotlinDslProject/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /examples/exampleKotlinDslProject/lib/protos-test.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/protobuf-gradle-plugin/0cce976ae1fcb35f29ec67d418a52b8622105c67/examples/exampleKotlinDslProject/lib/protos-test.tar.gz -------------------------------------------------------------------------------- /examples/exampleKotlinDslProject/lib/protos.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/protobuf-gradle-plugin/0cce976ae1fcb35f29ec67d418a52b8622105c67/examples/exampleKotlinDslProject/lib/protos.tar.gz -------------------------------------------------------------------------------- /examples/exampleKotlinDslProject/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "exampleProject" 2 | -------------------------------------------------------------------------------- /examples/exampleKotlinDslProject/src/main/java/Foo.java: -------------------------------------------------------------------------------- 1 | import com.google.protobuf.MessageLite; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Foo { 7 | public static List getDefaultInstances() { 8 | ArrayList list = new ArrayList(); 9 | // from src/main/proto/test.proto 10 | list.add(ws.antonov.protobuf.test.Test.TestMessage.getDefaultInstance()); 11 | list.add(ws.antonov.protobuf.test.Test.AnotherMessage.getDefaultInstance()); 12 | list.add(ws.antonov.protobuf.test.Test.Item.getDefaultInstance()); 13 | list.add(ws.antonov.protobuf.test.Test.DataMap.getDefaultInstance()); 14 | // from src/main/proto/sample.proto (java_multiple_files == true, thus no outter class) 15 | list.add(com.example.tutorial.Msg.getDefaultInstance()); 16 | list.add(com.example.tutorial.SecondMsg.getDefaultInstance()); 17 | // from lib/protos.tar.gz/stuff.proto 18 | list.add(Stuff.Blah.getDefaultInstance()); 19 | // from ext/more.proto 20 | list.add(More.MoreMsg.getDefaultInstance()); 21 | list.add(More.Foo.getDefaultInstance()); 22 | // from ext/test1.proto 23 | list.add(Test1.Test1Msg.getDefaultInstance()); 24 | // from ext/test2.proto 25 | list.add(Test2.Test2Msg.getDefaultInstance()); 26 | return list; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/exampleKotlinDslProject/src/main/proto/com/example/tutorial/sample.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | option java_package = "com.example.tutorial"; 4 | option java_outer_classname = "OuterSample"; 5 | option java_multiple_files = true; 6 | 7 | 8 | message Msg { 9 | string foo = 1; 10 | SecondMsg blah = 2; 11 | } 12 | 13 | message SecondMsg { 14 | int32 blah = 1; 15 | } 16 | -------------------------------------------------------------------------------- /examples/exampleKotlinDslProject/src/main/proto/io/grpc/testing/integration/empty.proto: -------------------------------------------------------------------------------- 1 | 2 | // Copyright 2015, Google Inc. 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto2"; 32 | 33 | package grpc.testing; 34 | 35 | option java_package = "com.google.protobuf"; 36 | option java_outer_classname = "EmptyProtos"; 37 | 38 | // An empty message that you can re-use to avoid defining duplicated empty 39 | // messages in your project. A typical example is to use it as argument or the 40 | // return value of a service API. For instance: 41 | // 42 | // service Foo { 43 | // rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { }; 44 | // }; 45 | // 46 | message Empty {} -------------------------------------------------------------------------------- /examples/exampleKotlinDslProject/src/main/proto/io/grpc/testing/integration/test.proto: -------------------------------------------------------------------------------- 1 | 2 | // Copyright 2015, Google Inc. 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // An integration test service that covers all the method signature permutations 32 | // of unary/streaming requests/responses. 33 | syntax = "proto3"; 34 | 35 | import "io/grpc/testing/integration/empty.proto"; 36 | import "io/grpc/testing/integration/messages.proto"; 37 | 38 | package grpc.testing; 39 | 40 | option java_package = "io.grpc.testing.integration"; 41 | 42 | // A simple service to test the various types of RPCs and experiment with 43 | // performance with various types of payload. 44 | service TestService { 45 | // One empty request followed by one empty response. 46 | rpc EmptyCall(grpc.testing.Empty) returns (grpc.testing.Empty); 47 | 48 | // One request followed by one response. 49 | rpc UnaryCall(SimpleRequest) returns (SimpleResponse); 50 | 51 | // One request followed by a sequence of responses (streamed download). 52 | // The server returns the payload with client desired type and sizes. 53 | rpc StreamingOutputCall(StreamingOutputCallRequest) 54 | returns (stream StreamingOutputCallResponse); 55 | 56 | // A sequence of requests followed by one response (streamed upload). 57 | // The server returns the aggregated size of client payload as the result. 58 | rpc StreamingInputCall(stream StreamingInputCallRequest) 59 | returns (StreamingInputCallResponse); 60 | 61 | // A sequence of requests with each request served by the server immediately. 62 | // As one request could lead to multiple responses, this interface 63 | // demonstrates the idea of full duplexing. 64 | rpc FullDuplexCall(stream StreamingOutputCallRequest) 65 | returns (stream StreamingOutputCallResponse); 66 | 67 | // A sequence of requests followed by a sequence of responses. 68 | // The server buffers all the client requests and then serves them in order. A 69 | // stream of responses are returned to the client when the server starts with 70 | // first request. 71 | rpc HalfDuplexCall(stream StreamingOutputCallRequest) 72 | returns (stream StreamingOutputCallResponse); 73 | } 74 | -------------------------------------------------------------------------------- /examples/exampleKotlinDslProject/src/main/proto/ws/antonov/protobuf/test/test.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package ws.antonov.protobuf.test; 4 | 5 | import "com/example/tutorial/sample.proto"; 6 | 7 | message TestMessage { 8 | int32 id = 1; 9 | string name = 2; 10 | } 11 | 12 | message AnotherMessage { 13 | repeated string names = 1; 14 | DataPayload data = 2; 15 | 16 | message DataPayload { 17 | string payload = 1; 18 | } 19 | } 20 | 21 | message Item { 22 | string name = 1; 23 | string value = 2; 24 | Msg msg = 3; 25 | SecondMsg msg2 = 4; 26 | } 27 | message DataMap { 28 | repeated Item data_items = 1; 29 | } 30 | -------------------------------------------------------------------------------- /examples/exampleKotlinDslProject/src/test/java/FooTest.java: -------------------------------------------------------------------------------- 1 | import static org.junit.Assert.assertEquals; 2 | import static org.junit.Assert.assertTrue; 3 | 4 | public class FooTest { 5 | @org.junit.Test 6 | public void testMainProtos() { 7 | assertEquals(11, Foo.getDefaultInstances().size()); 8 | } 9 | 10 | @org.junit.Test 11 | public void testTestProtos() { 12 | // from src/test/proto/test.proto 13 | Test.MsgTest.getDefaultInstance(); 14 | // from lib/protos-test.tar.gz 15 | test.Stuff.BlahTest.getDefaultInstance(); 16 | } 17 | 18 | @org.junit.Test 19 | public void testGrpc() { 20 | // from src/grpc/proto/ 21 | assertTrue(com.google.protobuf.GeneratedMessageV3.class.isAssignableFrom( 22 | io.grpc.testing.integration.Messages.SimpleRequest.class)); 23 | assertTrue(Object.class.isAssignableFrom(io.grpc.testing.integration.TestServiceGrpc.class)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/exampleKotlinDslProject/src/test/proto/test.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | // From the main sourceSet 4 | import "com/example/tutorial/sample.proto"; 5 | 6 | message MsgTest { 7 | Msg msg = 1; 8 | } 9 | -------------------------------------------------------------------------------- /examples/exampleProject/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .gradle 3 | build 4 | local.properties 5 | -------------------------------------------------------------------------------- /examples/exampleProject/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/protobuf-gradle-plugin/0cce976ae1fcb35f29ec67d418a52b8622105c67/examples/exampleProject/README.md -------------------------------------------------------------------------------- /examples/exampleProject/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id('java') 3 | id('idea') 4 | id('com.google.protobuf') version '0.9.4' 5 | } 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | 11 | dependencies { 12 | implementation 'com.google.protobuf:protobuf-java:3.6.1' 13 | implementation 'io.grpc:grpc-stub:1.15.1' 14 | implementation 'io.grpc:grpc-protobuf:1.15.1' 15 | 16 | if (JavaVersion.current().isJava9Compatible()) { 17 | // Workaround for @javax.annotation.Generated 18 | // see: https://github.com/grpc/grpc-java/issues/3633 19 | implementation 'javax.annotation:javax.annotation-api:1.3.1' 20 | } 21 | 22 | // Extra proto source files besides the ones residing under 23 | // "src/main". 24 | protobuf files("lib/protos.tar.gz") 25 | protobuf files("ext/") 26 | 27 | testImplementation 'junit:junit:4.12' 28 | // Extra proto source files for test besides the ones residing under 29 | // "src/test". 30 | testProtobuf files("lib/protos-test.tar.gz") 31 | } 32 | 33 | protobuf { 34 | protoc { 35 | // The artifact spec for the Protobuf Compiler 36 | artifact = 'com.google.protobuf:protoc:3.6.1' 37 | } 38 | plugins { 39 | // Optional: an artifact spec for a protoc plugin, with "grpc" as 40 | // the identifier, which can be referred to in the "plugins" 41 | // container of the "generateProtoTasks" closure. 42 | grpc { 43 | artifact = 'io.grpc:protoc-gen-grpc-java:1.15.1' 44 | } 45 | } 46 | generateProtoTasks { 47 | ofSourceSet('main').configureEach { 48 | plugins { 49 | // Apply the "grpc" plugin whose spec is defined above, without 50 | // options. Note the braces cannot be omitted, otherwise the 51 | // plugin will not be added. This is because of the implicit way 52 | // NamedDomainObjectContainer binds the methods. 53 | grpc { } 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /examples/exampleProject/ext/more.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | message MoreMsg { 4 | string bar = 1; 5 | } 6 | 7 | message Foo { 8 | string stuff = 1; 9 | } 10 | -------------------------------------------------------------------------------- /examples/exampleProject/ext/test1.proto: -------------------------------------------------------------------------------- 1 | /** 2 | * Created with IntelliJ IDEA. 3 | * User: aantonov 4 | * Date: 1/17/13 5 | * Time: 3:44 PM 6 | * To change this template use File | Settings | File Templates. 7 | */ 8 | syntax = "proto3"; 9 | 10 | message Test1Msg { 11 | string bar = 1; 12 | } 13 | -------------------------------------------------------------------------------- /examples/exampleProject/ext/test2.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | message Test2Msg { 4 | string bar = 1; 5 | } 6 | -------------------------------------------------------------------------------- /examples/exampleProject/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/protobuf-gradle-plugin/0cce976ae1fcb35f29ec67d418a52b8622105c67/examples/exampleProject/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /examples/exampleProject/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /examples/exampleProject/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /examples/exampleProject/lib/protos-test.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/protobuf-gradle-plugin/0cce976ae1fcb35f29ec67d418a52b8622105c67/examples/exampleProject/lib/protos-test.tar.gz -------------------------------------------------------------------------------- /examples/exampleProject/lib/protos.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/protobuf-gradle-plugin/0cce976ae1fcb35f29ec67d418a52b8622105c67/examples/exampleProject/lib/protos.tar.gz -------------------------------------------------------------------------------- /examples/exampleProject/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = "exampleProject" -------------------------------------------------------------------------------- /examples/exampleProject/src/main/java/Foo.java: -------------------------------------------------------------------------------- 1 | import com.google.protobuf.MessageLite; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Foo { 7 | public static List getDefaultInstances() { 8 | ArrayList list = new ArrayList(); 9 | // from src/main/proto/test.proto 10 | list.add(ws.antonov.protobuf.test.Test.TestMessage.getDefaultInstance()); 11 | list.add(ws.antonov.protobuf.test.Test.AnotherMessage.getDefaultInstance()); 12 | list.add(ws.antonov.protobuf.test.Test.Item.getDefaultInstance()); 13 | list.add(ws.antonov.protobuf.test.Test.DataMap.getDefaultInstance()); 14 | // from src/main/proto/sample.proto (java_multiple_files == true, thus no outter class) 15 | list.add(com.example.tutorial.Msg.getDefaultInstance()); 16 | list.add(com.example.tutorial.SecondMsg.getDefaultInstance()); 17 | // from lib/protos.tar.gz/stuff.proto 18 | list.add(Stuff.Blah.getDefaultInstance()); 19 | // from ext/more.proto 20 | list.add(More.MoreMsg.getDefaultInstance()); 21 | list.add(More.Foo.getDefaultInstance()); 22 | // from ext/test1.proto 23 | list.add(Test1.Test1Msg.getDefaultInstance()); 24 | // from ext/test2.proto 25 | list.add(Test2.Test2Msg.getDefaultInstance()); 26 | return list; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/exampleProject/src/main/proto/com/example/tutorial/sample.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | option java_package = "com.example.tutorial"; 4 | option java_outer_classname = "OuterSample"; 5 | option java_multiple_files = true; 6 | 7 | 8 | message Msg { 9 | string foo = 1; 10 | SecondMsg blah = 2; 11 | } 12 | 13 | message SecondMsg { 14 | int32 blah = 1; 15 | } 16 | -------------------------------------------------------------------------------- /examples/exampleProject/src/main/proto/io/grpc/testing/integration/empty.proto: -------------------------------------------------------------------------------- 1 | 2 | // Copyright 2015, Google Inc. 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto2"; 32 | 33 | package grpc.testing; 34 | 35 | option java_package = "com.google.protobuf"; 36 | option java_outer_classname = "EmptyProtos"; 37 | 38 | // An empty message that you can re-use to avoid defining duplicated empty 39 | // messages in your project. A typical example is to use it as argument or the 40 | // return value of a service API. For instance: 41 | // 42 | // service Foo { 43 | // rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { }; 44 | // }; 45 | // 46 | message Empty {} -------------------------------------------------------------------------------- /examples/exampleProject/src/main/proto/io/grpc/testing/integration/test.proto: -------------------------------------------------------------------------------- 1 | 2 | // Copyright 2015, Google Inc. 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // An integration test service that covers all the method signature permutations 32 | // of unary/streaming requests/responses. 33 | syntax = "proto3"; 34 | 35 | import "io/grpc/testing/integration/empty.proto"; 36 | import "io/grpc/testing/integration/messages.proto"; 37 | 38 | package grpc.testing; 39 | 40 | option java_package = "io.grpc.testing.integration"; 41 | 42 | // A simple service to test the various types of RPCs and experiment with 43 | // performance with various types of payload. 44 | service TestService { 45 | // One empty request followed by one empty response. 46 | rpc EmptyCall(grpc.testing.Empty) returns (grpc.testing.Empty); 47 | 48 | // One request followed by one response. 49 | rpc UnaryCall(SimpleRequest) returns (SimpleResponse); 50 | 51 | // One request followed by a sequence of responses (streamed download). 52 | // The server returns the payload with client desired type and sizes. 53 | rpc StreamingOutputCall(StreamingOutputCallRequest) 54 | returns (stream StreamingOutputCallResponse); 55 | 56 | // A sequence of requests followed by one response (streamed upload). 57 | // The server returns the aggregated size of client payload as the result. 58 | rpc StreamingInputCall(stream StreamingInputCallRequest) 59 | returns (StreamingInputCallResponse); 60 | 61 | // A sequence of requests with each request served by the server immediately. 62 | // As one request could lead to multiple responses, this interface 63 | // demonstrates the idea of full duplexing. 64 | rpc FullDuplexCall(stream StreamingOutputCallRequest) 65 | returns (stream StreamingOutputCallResponse); 66 | 67 | // A sequence of requests followed by a sequence of responses. 68 | // The server buffers all the client requests and then serves them in order. A 69 | // stream of responses are returned to the client when the server starts with 70 | // first request. 71 | rpc HalfDuplexCall(stream StreamingOutputCallRequest) 72 | returns (stream StreamingOutputCallResponse); 73 | } 74 | -------------------------------------------------------------------------------- /examples/exampleProject/src/main/proto/ws/antonov/protobuf/test/test.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package ws.antonov.protobuf.test; 4 | 5 | import "com/example/tutorial/sample.proto"; 6 | 7 | message TestMessage { 8 | int32 id = 1; 9 | string name = 2; 10 | } 11 | 12 | message AnotherMessage { 13 | repeated string names = 1; 14 | DataPayload data = 2; 15 | 16 | message DataPayload { 17 | string payload = 1; 18 | } 19 | } 20 | 21 | message Item { 22 | string name = 1; 23 | string value = 2; 24 | Msg msg = 3; 25 | SecondMsg msg2 = 4; 26 | } 27 | message DataMap { 28 | repeated Item data_items = 1; 29 | } 30 | -------------------------------------------------------------------------------- /examples/exampleProject/src/test/java/FooTest.java: -------------------------------------------------------------------------------- 1 | import static org.junit.Assert.assertEquals; 2 | import static org.junit.Assert.assertTrue; 3 | 4 | public class FooTest { 5 | @org.junit.Test 6 | public void testMainProtos() { 7 | assertEquals(11, Foo.getDefaultInstances().size()); 8 | } 9 | 10 | @org.junit.Test 11 | public void testTestProtos() { 12 | // from src/test/proto/test.proto 13 | Test.MsgTest.getDefaultInstance(); 14 | // from lib/protos-test.tar.gz 15 | test.Stuff.BlahTest.getDefaultInstance(); 16 | } 17 | 18 | @org.junit.Test 19 | public void testGrpc() { 20 | // from src/grpc/proto/ 21 | assertTrue(com.google.protobuf.GeneratedMessageV3.class.isAssignableFrom( 22 | io.grpc.testing.integration.Messages.SimpleRequest.class)); 23 | assertTrue(Object.class.isAssignableFrom(io.grpc.testing.integration.TestServiceGrpc.class)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/exampleProject/src/test/proto/test.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | // From the main sourceSet 4 | import "com/example/tutorial/sample.proto"; 5 | 6 | message MsgTest { 7 | Msg msg = 1; 8 | } 9 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/protobuf-gradle-plugin/0cce976ae1fcb35f29ec67d418a52b8622105c67/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'protobuf-gradle-plugin' -------------------------------------------------------------------------------- /src/main/groovy/com/google/protobuf/gradle/ArchiveActionFacade.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Google Inc. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this 8 | * list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors 15 | * may be used to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | package com.google.protobuf.gradle; 30 | 31 | import groovy.transform.CompileStatic; 32 | import org.gradle.api.Project; 33 | import org.gradle.api.file.ArchiveOperations; 34 | import org.gradle.api.file.FileTree; 35 | import org.gradle.api.internal.file.FileOperations; 36 | 37 | import javax.inject.Inject; 38 | 39 | @CompileStatic 40 | public interface ArchiveActionFacade { 41 | 42 | FileTree zipTree(Object path); 43 | 44 | FileTree tarTree(Object path); 45 | 46 | @CompileStatic 47 | class ProjectBased implements ArchiveActionFacade { 48 | 49 | private final Project project; 50 | 51 | ProjectBased(Project project) { 52 | this.project = project; 53 | } 54 | 55 | @Override 56 | public FileTree zipTree(Object path) { 57 | return project.zipTree(path); 58 | } 59 | 60 | @Override 61 | public FileTree tarTree(Object path) { 62 | return project.tarTree(path); 63 | } 64 | } 65 | 66 | @CompileStatic 67 | abstract class InternalServiceBased implements ArchiveActionFacade { 68 | 69 | @Inject 70 | public abstract FileOperations getFileOperations(); 71 | 72 | @Override 73 | public FileTree zipTree(Object path) { 74 | return getFileOperations().zipTree(path); 75 | } 76 | 77 | @Override 78 | public FileTree tarTree(Object path) { 79 | return getFileOperations().tarTree(path); 80 | } 81 | } 82 | 83 | @CompileStatic 84 | abstract class ServiceBased implements ArchiveActionFacade { 85 | 86 | @Inject 87 | public abstract ArchiveOperations getArchiveOperations(); 88 | 89 | @Override 90 | public FileTree zipTree(Object path) { 91 | return getArchiveOperations().zipTree(path); 92 | } 93 | 94 | @Override 95 | public FileTree tarTree(Object path) { 96 | return getArchiveOperations().tarTree(path); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/groovy/com/google/protobuf/gradle/CopyActionFacade.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Original work copyright (c) 2015, Alex Antonov. All rights reserved. 3 | * Modified work copyright (c) 2015, Google Inc. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * 3. Neither the name of the copyright holder nor the names of its contributors 16 | * may be used to endorse or promote products derived from this software without 17 | * specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package com.google.protobuf.gradle; 31 | 32 | import groovy.transform.CompileStatic; 33 | import org.gradle.api.Action; 34 | import org.gradle.api.Project; 35 | import org.gradle.api.file.CopySpec; 36 | import org.gradle.api.file.DeleteSpec; 37 | import org.gradle.api.file.FileSystemOperations; 38 | import org.gradle.api.model.ObjectFactory; 39 | import org.gradle.api.tasks.WorkResult; 40 | import org.gradle.util.GradleVersion; 41 | 42 | import javax.inject.Inject; 43 | 44 | /** 45 | * Interface exposing the file copying feature. Actual implementations may use the 46 | * {@link org.gradle.api.file.FileSystemOperations} if available (Gradle 6.0+) or {@link org.gradle.api.Project#copy} if 47 | * the version of Gradle is below 6.0. 48 | */ 49 | @CompileStatic 50 | interface CopyActionFacade { 51 | WorkResult copy(Action var1); 52 | WorkResult delete(Action action); 53 | WorkResult sync(Action var1); 54 | 55 | @CompileStatic 56 | final class Loader { 57 | public static CopyActionFacade create(Project project, ObjectFactory objectFactory) { 58 | if (GradleVersion.current().compareTo(GradleVersion.version("6.0")) >= 0) { 59 | // Use object factory to instantiate as that will inject the necessary service. 60 | return objectFactory.newInstance(CopyActionFacade.FileSystemOperationsBased.class); 61 | } 62 | return new CopyActionFacade.ProjectBased(project); 63 | } 64 | } 65 | 66 | @CompileStatic 67 | class ProjectBased implements CopyActionFacade { 68 | private final Project project; 69 | 70 | public ProjectBased(Project project) { 71 | this.project = project; 72 | } 73 | 74 | @Override 75 | public WorkResult copy(Action action) { 76 | return project.copy(action); 77 | } 78 | 79 | @Override 80 | public WorkResult delete(Action action) { 81 | return project.delete(action); 82 | } 83 | 84 | @Override 85 | public WorkResult sync(Action action) { 86 | return project.sync(action); 87 | } 88 | } 89 | 90 | @CompileStatic 91 | abstract class FileSystemOperationsBased implements CopyActionFacade { 92 | @Inject 93 | public abstract FileSystemOperations getFileSystemOperations(); 94 | 95 | @Override 96 | public WorkResult copy(Action action) { 97 | return getFileSystemOperations().copy(action); 98 | } 99 | 100 | @Override 101 | public WorkResult delete(Action action) { 102 | return getFileSystemOperations().delete(action); 103 | } 104 | 105 | @Override 106 | public WorkResult sync(Action action) { 107 | return getFileSystemOperations().sync(action); 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/groovy/com/google/protobuf/gradle/ExecutableLocator.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Google Inc. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this 8 | * list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors 15 | * may be used to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | package com.google.protobuf.gradle 30 | 31 | import groovy.transform.CompileStatic 32 | import groovy.transform.PackageScope 33 | import org.gradle.api.Named 34 | import org.gradle.api.file.FileCollection 35 | 36 | /** 37 | * Locates an executable that can either be found locally or downloaded from 38 | * repositories. If configured multiple times, the last call wins. If never 39 | * configured, the plugin should try to run the executable from system search 40 | * path. 41 | */ 42 | @CompileStatic 43 | class ExecutableLocator implements Named { 44 | 45 | private final String name 46 | 47 | private String artifact 48 | private String path 49 | 50 | private FileCollection artifactFiles 51 | private String simplifiedArtifactName 52 | 53 | ExecutableLocator(String name) { 54 | this.name = name 55 | } 56 | 57 | @Override 58 | String getName() { 59 | return name 60 | } 61 | 62 | /** 63 | * Specifies an artifact spec for downloading the executable from 64 | * repositories. spec format: '::' 65 | */ 66 | void setArtifact(String spec) { 67 | this.artifact = spec 68 | this.path = null 69 | } 70 | 71 | /** 72 | * Specifies a local path. 73 | */ 74 | void setPath(String path) { 75 | this.path = path 76 | this.artifact = null 77 | } 78 | 79 | String getArtifact() { 80 | return artifact 81 | } 82 | 83 | String getPath() { 84 | return path 85 | } 86 | 87 | @PackageScope 88 | FileCollection getArtifactFiles() { 89 | Preconditions.checkState(path == null, 'Not artifact based') 90 | Preconditions.checkState(artifactFiles != null, 'Not yet created resolved') 91 | return artifactFiles 92 | } 93 | 94 | @PackageScope 95 | String getSimplifiedArtifactName() { 96 | Preconditions.checkState(path == null, 'Not artifact based') 97 | Preconditions.checkState(simplifiedArtifactName != null, 'Not yet resolved') 98 | return simplifiedArtifactName 99 | } 100 | 101 | @PackageScope 102 | void resolve(FileCollection artifactFiles, String simplifiedArtifactName) { 103 | this.artifactFiles = artifactFiles 104 | this.simplifiedArtifactName = simplifiedArtifactName 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/main/groovy/com/google/protobuf/gradle/Preconditions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, Google Inc. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this 8 | * list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors 15 | * may be used to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | package com.google.protobuf.gradle; 30 | 31 | /** 32 | * Common assertions helper. 33 | */ 34 | final class Preconditions { 35 | private Preconditions() {} // prevent instantiation 36 | 37 | public static void checkState(boolean expectedState) { 38 | if (!expectedState) { 39 | throw new IllegalStateException(); 40 | } 41 | } 42 | 43 | public static void checkState(boolean expectedState, Object errorMessage) { 44 | if (!expectedState) { 45 | throw new IllegalStateException(String.valueOf(errorMessage)); 46 | } 47 | } 48 | 49 | public static T checkNotNull(T obj, Object errorMessage) { 50 | if (obj == null) { 51 | throw new NullPointerException(String.valueOf(errorMessage)); 52 | } 53 | return obj; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/groovy/com/google/protobuf/gradle/ToolsLocator.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Google Inc. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this 8 | * list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors 15 | * may be used to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | package com.google.protobuf.gradle 30 | 31 | import com.google.gradle.osdetector.OsDetector 32 | import groovy.transform.CompileStatic 33 | import org.gradle.api.NamedDomainObjectContainer 34 | import org.gradle.api.Project 35 | import org.gradle.api.artifacts.Configuration 36 | 37 | /** 38 | * Holds locations of all external executables, i.e., protoc and plugins. 39 | */ 40 | @CompileStatic 41 | class ToolsLocator { 42 | 43 | final ExecutableLocator protoc 44 | final NamedDomainObjectContainer plugins 45 | 46 | static List artifactParts(String artifactCoordinate) { 47 | String artifact 48 | String extension 49 | String group 50 | String name 51 | String version 52 | String classifier 53 | 54 | List artifactCoordinateTokenized = artifactCoordinate.tokenize('@') 55 | (artifact, extension) = [artifactCoordinateTokenized[0], artifactCoordinateTokenized[1]] 56 | if (extension == null && artifactCoordinate.endsWith('@')) { 57 | extension = '' 58 | } 59 | List artifactTokenized = artifact.tokenize(':') 60 | (group, name, version, classifier) = 61 | [artifactTokenized[0], artifactTokenized[1], artifactTokenized[2], artifactTokenized[3]] 62 | 63 | return [group, name, version, classifier, extension] 64 | } 65 | 66 | ToolsLocator(Project project) { 67 | protoc = new ExecutableLocator('protoc') 68 | plugins = project.container(ExecutableLocator) 69 | } 70 | 71 | /** 72 | * For every ExecutableLocator that points to an artifact spec: creates a 73 | * project configuration dependency for that artifact, registers the 74 | * configuration dependency as an input dependency with the specified tasks, 75 | * and adds a doFirst {} block to the specified tasks which resolves the 76 | * spec, downloads the artifact, and point to the local path. 77 | */ 78 | void resolve(Project project) { 79 | if (protoc.artifact != null) { 80 | resolveLocator(project, protoc) 81 | } else if (protoc.path == null) { 82 | protoc.path = 'protoc' 83 | } 84 | for (ExecutableLocator pluginLocator in plugins) { 85 | if (pluginLocator.artifact != null) { 86 | resolveLocator(project, pluginLocator) 87 | } else if (pluginLocator.path == null) { 88 | pluginLocator.path = "protoc-gen-${pluginLocator.name}" 89 | } 90 | } 91 | } 92 | 93 | private void resolveLocator(Project project, ExecutableLocator locator) { 94 | // create a project configuration dependency for the artifact 95 | Configuration config = project.configurations.create("protobufToolsLocator_${locator.name}") { Configuration conf -> 96 | conf.visible = false 97 | conf.transitive = false 98 | } 99 | String groupId, artifact, version, classifier, extension 100 | OsDetector osdetector = project.extensions.getByName("osdetector") as OsDetector 101 | List parts = artifactParts(locator.artifact) 102 | (groupId, artifact, version, classifier, extension) = [parts[0], parts[1], parts[2], parts[3], parts[4]] 103 | Map notation = [ 104 | group:groupId, 105 | name:artifact, 106 | version:version, 107 | classifier:classifier ?: osdetector.classifier, 108 | ext:extension ?: 'exe', 109 | ] 110 | project.dependencies.add(config.name, notation) 111 | locator.resolve(config, "$groupId:$artifact:$version".toString()) 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/main/groovy/com/google/protobuf/gradle/internal/DefaultProtoSourceSet.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, Google Inc. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this 8 | * list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors 15 | * may be used to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | package com.google.protobuf.gradle.internal 30 | 31 | import com.google.protobuf.gradle.tasks.ProtoSourceSet 32 | import groovy.transform.CompileStatic 33 | import org.gradle.api.file.ConfigurableFileCollection 34 | import org.gradle.api.file.SourceDirectorySet 35 | import org.gradle.api.model.ObjectFactory 36 | 37 | @CompileStatic 38 | class DefaultProtoSourceSet implements ProtoSourceSet { 39 | private final String name 40 | private final SourceDirectorySet proto 41 | private final ConfigurableFileCollection includeProtoDirs 42 | private final ConfigurableFileCollection output 43 | 44 | DefaultProtoSourceSet(String name, ObjectFactory objects) { 45 | this.name = name 46 | this.proto = objects.sourceDirectorySet("proto", "${name.capitalize()} Proto Source") 47 | this.includeProtoDirs = objects.fileCollection() 48 | this.output = objects.fileCollection() 49 | } 50 | 51 | @Override 52 | String getName() { 53 | return this.name 54 | } 55 | 56 | @Override 57 | SourceDirectorySet getProto() { 58 | return this.proto 59 | } 60 | 61 | @Override 62 | ConfigurableFileCollection getIncludeProtoDirs() { 63 | return this.includeProtoDirs 64 | } 65 | 66 | @Override 67 | ConfigurableFileCollection getOutput() { 68 | return this.output 69 | } 70 | 71 | @Override 72 | void includesFrom(ProtoSourceSet protoSourceSet) { 73 | this.includeProtoDirs.from(protoSourceSet.proto.sourceDirectories) 74 | this.includeProtoDirs.from(protoSourceSet.includeProtoDirs) 75 | } 76 | 77 | @Override 78 | void extendsFrom(ProtoSourceSet protoSourceSet) { 79 | this.proto.source(protoSourceSet.proto) 80 | this.includeProtoDirs.from(protoSourceSet.includeProtoDirs) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/groovy/com/google/protobuf/gradle/internal/ProjectExt.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, Google Inc. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this 8 | * list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors 15 | * may be used to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | package com.google.protobuf.gradle.internal 30 | 31 | import com.android.build.gradle.AppExtension 32 | import com.android.build.gradle.BaseExtension 33 | import com.android.build.gradle.LibraryExtension 34 | import com.android.build.gradle.TestExtension 35 | import com.android.build.gradle.TestedExtension 36 | import com.android.build.gradle.api.BaseVariant 37 | import groovy.transform.CompileStatic 38 | import org.gradle.api.Action 39 | import org.gradle.api.Project 40 | 41 | @CompileStatic 42 | class ProjectExt { 43 | private ProjectExt() { 44 | } 45 | 46 | @SuppressWarnings(["CouldBeSwitchStatement"]) // `if` is better than fallthrough `switch` 47 | static void forEachVariant(final Project project, final Action action) { 48 | BaseExtension android = project.extensions.getByName("android") as BaseExtension 49 | project.logger.debug("$project has '$android'") 50 | 51 | if (android instanceof AppExtension) { 52 | (android as AppExtension).getApplicationVariants().all(action) 53 | } 54 | 55 | if (android instanceof LibraryExtension) { 56 | (android as LibraryExtension).getLibraryVariants().all(action) 57 | } 58 | 59 | if (android instanceof TestExtension) { 60 | (android as TestExtension).getApplicationVariants().all(action) 61 | } 62 | 63 | if (android instanceof TestedExtension) { 64 | (android as TestedExtension).getTestVariants().all(action) 65 | (android as TestedExtension).getUnitTestVariants().all(action) 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/groovy/com/google/protobuf/gradle/tasks/ProtoSourceSet.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, Google Inc. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this 8 | * list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors 15 | * may be used to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | package com.google.protobuf.gradle.tasks 30 | 31 | import groovy.transform.CompileStatic 32 | import org.gradle.api.file.ConfigurableFileCollection 33 | import org.gradle.api.file.SourceDirectorySet 34 | 35 | @CompileStatic 36 | interface ProtoSourceSet { 37 | String getName() 38 | 39 | SourceDirectorySet getProto() 40 | 41 | ConfigurableFileCollection getIncludeProtoDirs() 42 | 43 | ConfigurableFileCollection getOutput() 44 | 45 | void includesFrom(ProtoSourceSet protoSourceSet) 46 | 47 | void extendsFrom(ProtoSourceSet protoSourceSet) 48 | } 49 | -------------------------------------------------------------------------------- /src/main/kotlin/com/google/protobuf/gradle/ProtobufConfiguratorExts.kt: -------------------------------------------------------------------------------- 1 | package com.google.protobuf.gradle 2 | 3 | import com.android.build.api.dsl.AndroidSourceSet 4 | import com.android.build.gradle.api.AndroidSourceSet as DeprecatedAndroidSourceSet 5 | import org.gradle.api.NamedDomainObjectContainer 6 | import org.gradle.api.file.SourceDirectorySet 7 | import org.gradle.api.plugins.ExtensionAware 8 | import org.gradle.api.tasks.SourceSet 9 | import org.gradle.kotlin.dsl.get 10 | 11 | /** 12 | * Applies the supplied action to the "proto" [SourceDirectorySet] extension on 13 | * a receiver of type [SourceSet]. 14 | * 15 | * @since 0.8.7 16 | * @usage 17 | * ``` 18 | * sourceSets { 19 | * create("sample") { 20 | * proto { 21 | * srcDir("src/sample/protobuf") 22 | * } 23 | * } 24 | * } 25 | * ``` 26 | * 27 | * @receiver [SourceSet] The source set for which the "proto" [SourceDirectorySet] extension 28 | * will be configured 29 | * 30 | * @param action A configuration lambda to apply on a receiver of type [SourceDirectorySet] 31 | * @return [Unit] 32 | */ 33 | fun SourceSet.proto(action: SourceDirectorySet.() -> Unit) { 34 | (this as? ExtensionAware) 35 | ?.extensions 36 | ?.getByName("proto") 37 | ?.let { it as? SourceDirectorySet } 38 | ?.apply(action) 39 | } 40 | 41 | /** 42 | * Applies the supplied action to the "proto" [SourceDirectorySet] extension on 43 | * a receiver of type [DeprecatedAndroidSourceSet] for Android builds. 44 | * 45 | * @since 0.8.15 46 | * @usage 47 | * ``` 48 | * android { 49 | * sourceSets { 50 | * create("sample") { 51 | * proto { 52 | * srcDir("src/sample/protobuf") 53 | * } 54 | * } 55 | * } 56 | * } 57 | * ``` 58 | * 59 | * @receiver [DeprecatedAndroidSourceSet] The Android source set for which the "proto" 60 | * [SourceDirectorySet] extension will be configured 61 | * 62 | * @param action A configuration lambda to apply on a receiver of type [SourceDirectorySet] 63 | * @return [Unit] 64 | */ 65 | fun DeprecatedAndroidSourceSet.proto(action: SourceDirectorySet.() -> Unit) { 66 | (this as? ExtensionAware) 67 | ?.extensions 68 | ?.getByName("proto") 69 | ?.let { it as? SourceDirectorySet } 70 | ?.apply(action) 71 | } 72 | 73 | /** 74 | * Applies the supplied action to the "proto" [SourceDirectorySet] extension on 75 | * a receiver of type [AndroidSourceSet] for Android builds. 76 | * 77 | * @since 0.9.0 78 | * @usage 79 | * ``` 80 | * android { 81 | * sourceSets { 82 | * create("sample") { 83 | * proto { 84 | * srcDir("src/sample/protobuf") 85 | * } 86 | * } 87 | * } 88 | * } 89 | * ``` 90 | * 91 | * @receiver [AndroidSourceSet] The Android source set for which the "proto" 92 | * [SourceDirectorySet] extension will be configured 93 | * 94 | * @param action A configuration lambda to apply on a receiver of type [SourceDirectorySet] 95 | * @return [Unit] 96 | */ 97 | fun AndroidSourceSet.proto(action: SourceDirectorySet.() -> Unit) { 98 | (this as? ExtensionAware) 99 | ?.extensions 100 | ?.getByName("proto") 101 | ?.let { it as? SourceDirectorySet } 102 | ?.apply(action) 103 | } 104 | 105 | /** 106 | * An extension for creating and configuring the elements of an instance of [NamedDomainObjectContainer]. 107 | * 108 | * @since 0.9.0 109 | * @usage 110 | * ``` 111 | * protobuf { 112 | * plugins { 113 | * id("grpc") { 114 | * artifact = "io.grpc:protoc-gen-grpc-java:1.15.1" 115 | * } 116 | * } 117 | * } 118 | * ``` 119 | * 120 | * @receiver [NamedDomainObjectContainer] The scope of the [NamedDomainObjectContainer] 121 | * on which to create or configure an element. 122 | * 123 | * @param id The string id of the element to create or configure. 124 | * @param action An optional action that will be applied to the element instance. 125 | * 126 | * @return [Unit] 127 | */ 128 | fun NamedDomainObjectContainer.id(id: String, action: (T.() -> Unit)? = null) { 129 | action?.let { create(id, it) } ?: create(id) 130 | } 131 | 132 | /** 133 | * An extension for removing an element by id on an instance of [NamedDomainObjectContainer]. 134 | * 135 | * @since 0.9.0 136 | * @usage 137 | * ``` 138 | * protobuf { 139 | * generateProtoTasks { 140 | * ofSourceSet("main").forEach { 141 | * it.builtins { 142 | * remove("java") 143 | * } 144 | * } 145 | * } 146 | * } 147 | * ``` 148 | * 149 | * @receiver [NamedDomainObjectContainer] The scope of the [NamedDomainObjectContainer] 150 | * on which to remove an element. 151 | * 152 | * @param id The string id of the element to remove. 153 | * 154 | * @return [Unit] 155 | */ 156 | fun NamedDomainObjectContainer.remove(id: String) { 157 | remove(this[id]) 158 | } 159 | -------------------------------------------------------------------------------- /src/main/kotlin/com/google/protobuf/gradle/ProtobufDependencyConfiguration.kt: -------------------------------------------------------------------------------- 1 | package com.google.protobuf.gradle 2 | 3 | import org.gradle.api.artifacts.Configuration 4 | import org.gradle.api.artifacts.ConfigurationContainer 5 | import org.gradle.api.artifacts.Dependency 6 | import org.gradle.api.artifacts.ExternalModuleDependency 7 | import org.gradle.api.artifacts.ModuleDependency 8 | import org.gradle.api.artifacts.dsl.DependencyHandler 9 | import org.gradle.kotlin.dsl.add 10 | import org.gradle.kotlin.dsl.create 11 | import kotlin.properties.ReadOnlyProperty 12 | import kotlin.reflect.KProperty 13 | 14 | 15 | val ConfigurationContainer.protobuf: Configuration 16 | get() = getByName("protobuf") 17 | 18 | val DependencyHandler.protobuf by ProtobufDependencyHelper 19 | 20 | val ConfigurationContainer.testProtobuf: Configuration 21 | get() = getByName("testProtobuf") 22 | 23 | val DependencyHandler.testProtobuf by ProtobufDependencyHelper 24 | 25 | class ProtobufDependencyHelper( 26 | private val configurationName: String, 27 | private val dependencyHandler: DependencyHandler 28 | ) { 29 | 30 | operator fun invoke(dependencyNotation: Any): Dependency? = 31 | dependencyHandler.add(configurationName, dependencyNotation) 32 | 33 | operator fun invoke( 34 | dependencyNotation: String, 35 | dependencyConfiguration: ExternalModuleDependency.() -> Unit 36 | ): ExternalModuleDependency = 37 | dependencyHandler.add(configurationName, dependencyNotation, dependencyConfiguration) 38 | 39 | operator fun invoke( 40 | group: String, 41 | name: String, 42 | version: String? = null, 43 | configuration: String? = null, 44 | classifier: String? = null, 45 | ext: String? = null 46 | ): ExternalModuleDependency = 47 | dependencyHandler.run { 48 | create(group, name, version, configuration, classifier, ext) 49 | .also { add(configurationName, it) } 50 | } 51 | 52 | operator fun invoke( 53 | group: String, 54 | name: String, 55 | version: String? = null, 56 | configuration: String? = null, 57 | classifier: String? = null, 58 | ext: String? = null, 59 | dependencyConfiguration: ExternalModuleDependency.() -> Unit 60 | ): ExternalModuleDependency = 61 | dependencyHandler.run { 62 | val dep = create(group, name, version, configuration, classifier, ext) 63 | add(configurationName, dep, dependencyConfiguration) 64 | } 65 | 66 | operator fun invoke( 67 | dependency: T, 68 | dependencyConfiguration: T.() -> Unit 69 | ): T = 70 | dependencyHandler.add(configurationName, dependency, dependencyConfiguration) 71 | 72 | companion object : ReadOnlyProperty { 73 | 74 | override fun getValue(thisRef: DependencyHandler, property: KProperty<*>): ProtobufDependencyHelper = 75 | ProtobufDependencyHelper(property.name, thisRef) 76 | } 77 | } -------------------------------------------------------------------------------- /src/test/groovy/com/google/protobuf/gradle/AndroidProjectDetectionTest.groovy: -------------------------------------------------------------------------------- 1 | package com.google.protobuf.gradle 2 | 3 | import groovy.transform.CompileDynamic 4 | import org.gradle.testkit.runner.BuildResult 5 | import org.gradle.testkit.runner.TaskOutcome 6 | import spock.lang.Specification 7 | import spock.lang.Unroll 8 | 9 | /** 10 | * Verify android projects are identified correctly 11 | */ 12 | @CompileDynamic 13 | class AndroidProjectDetectionTest extends Specification { 14 | private static final List GRADLE_VERSION = ["5.6", "7.4.2"] 15 | private static final List ANDROID_PLUGIN_VERSION = ["3.5.0", "7.2.1"] 16 | 17 | static void appendUtilIsAndroidProjectCheckTask(File buildFile, boolean assertResult) { 18 | buildFile << """ 19 | task checkForAndroidPlugin { 20 | doLast { 21 | boolean result = com.google.protobuf.gradle.Utils.isAndroidProject(project) 22 | println "isAndroidProject -> \$result" 23 | assert result == ${assertResult} 24 | } 25 | } 26 | """ 27 | } 28 | 29 | @Unroll 30 | void "test succeeds on android project [android #agpVersion, gradle #gradleVersion]"() { 31 | given: "a project with android plugin" 32 | File mainProjectDir = ProtobufPluginTestHelper.projectBuilder("singleModuleAndroidProject") 33 | .copyDirs('testProjectAndroid', 'testProjectAndroidBare') 34 | .withAndroidPlugin(agpVersion) 35 | .build() 36 | appendUtilIsAndroidProjectCheckTask(new File(mainProjectDir, "build.gradle"), true) 37 | 38 | when: "checkForAndroidPlugin task evaluates Utils.isAndroidProject" 39 | BuildResult result = ProtobufPluginTestHelper.getAndroidGradleRunner( 40 | mainProjectDir, 41 | gradleVersion, 42 | agpVersion, 43 | "checkForAndroidPlugin" 44 | ).build() 45 | 46 | then: "Utils.isAndroidProject evaluation matched assertion in task checkForAndroidPlugin" 47 | assert result.task(":checkForAndroidPlugin").outcome == TaskOutcome.SUCCESS 48 | 49 | where: 50 | agpVersion << ANDROID_PLUGIN_VERSION 51 | gradleVersion << GRADLE_VERSION 52 | } 53 | 54 | /** 55 | * Failing test case for https://github.com/google/protobuf-gradle-plugin/issues/236 56 | */ 57 | @Unroll 58 | void "test fails on sub project of android project [android #agpVersion, gradle #gradleVersion]"() { 59 | given: "an android root project and java sub project" 60 | File subProjectStaging = ProtobufPluginTestHelper.projectBuilder('subModuleTestProjectLite') 61 | .copyDirs('testProjectLite') 62 | .build() 63 | appendUtilIsAndroidProjectCheckTask(new File(subProjectStaging, "build.gradle"), false) 64 | 65 | File mainProjectDir = ProtobufPluginTestHelper.projectBuilder("rootModuleAndroidProject") 66 | .copyDirs('testProjectAndroid', 'testProjectAndroidBare') 67 | .copySubProjects(subProjectStaging) 68 | .withAndroidPlugin(agpVersion) 69 | .build() 70 | appendUtilIsAndroidProjectCheckTask(new File(mainProjectDir, "build.gradle"), true) 71 | 72 | when: "checkForAndroidPlugin task evaluates Utils.isAndroidProject" 73 | BuildResult result = ProtobufPluginTestHelper.getAndroidGradleRunner( 74 | mainProjectDir, 75 | gradleVersion, 76 | agpVersion, 77 | "checkForAndroidPlugin" 78 | ).build() 79 | 80 | then: "Utils.isAndroidProject evaluation matched assertion in task checkForAndroidPlugin" 81 | assert result.task(":checkForAndroidPlugin").outcome == TaskOutcome.SUCCESS 82 | assert result.task(":subModuleTestProjectLite:checkForAndroidPlugin").outcome == TaskOutcome.SUCCESS 83 | 84 | where: 85 | agpVersion << ANDROID_PLUGIN_VERSION 86 | gradleVersion << GRADLE_VERSION 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/test/groovy/com/google/protobuf/gradle/ProtobufAndroidPluginKotlinTest.groovy: -------------------------------------------------------------------------------- 1 | package com.google.protobuf.gradle 2 | 3 | import groovy.transform.CompileDynamic 4 | import org.gradle.testkit.runner.BuildResult 5 | import org.gradle.testkit.runner.TaskOutcome 6 | import spock.lang.Specification 7 | import spock.lang.Unroll 8 | 9 | @CompileDynamic 10 | class ProtobufAndroidPluginKotlinTest extends Specification { 11 | private static final List GRADLE_VERSION = ["5.6", "6.5.1", "7.4.2", "7.6.2", "7.6.2"] 12 | private static final List ANDROID_PLUGIN_VERSION = ["3.5.0", "4.1.0", "7.2.1", "7.3.1", "7.4.2"] 13 | private static final List KOTLIN_VERSION = ["1.3.20", "1.3.20", "1.3.40", "1.7.20", "1.9.0"] 14 | 15 | /** 16 | * This test may take a significant amount of Gradle daemon Metaspace memory in some 17 | * Gradle + AGP versions. Try running it separately 18 | */ 19 | @Unroll 20 | void "testProjectAndroidKotlin [android #agpVersion, gradle #gradleVersion, kotlin #kotlinVersion]"() { 21 | given: "project from testProject, testProjectLite & testProjectAndroid" 22 | File testProjectStaging = ProtobufPluginTestHelper.projectBuilder('testProject') 23 | .copyDirs('testProjectBase', 'testProject') 24 | .build() 25 | File testProjectAndroidStaging = ProtobufPluginTestHelper.projectBuilder('testProjectAndroid') 26 | .copyDirs('testProjectAndroidBase', 'testProjectAndroidKotlin') 27 | .build() 28 | File testProjectLiteStaging = ProtobufPluginTestHelper.projectBuilder('testProjectLite') 29 | .copyDirs('testProjectLite') 30 | .build() 31 | File mainProjectDir = ProtobufPluginTestHelper.projectBuilder('testProjectAndroidMain') 32 | .copySubProjects(testProjectStaging, testProjectLiteStaging, testProjectAndroidStaging) 33 | .withAndroidPlugin(agpVersion) 34 | .withKotlin(kotlinVersion) 35 | .build() 36 | when: "build is invoked" 37 | BuildResult result = ProtobufPluginTestHelper.getAndroidGradleRunner( 38 | mainProjectDir, 39 | gradleVersion, 40 | agpVersion, 41 | "testProjectAndroid:build" 42 | ).build() 43 | 44 | then: "it succeed" 45 | result.task(":testProjectAndroid:build").outcome == TaskOutcome.SUCCESS 46 | 47 | where: 48 | agpVersion << ANDROID_PLUGIN_VERSION 49 | gradleVersion << GRADLE_VERSION 50 | kotlinVersion << KOTLIN_VERSION 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/groovy/com/google/protobuf/gradle/ProtobufKotlinDslCopySpecTest.groovy: -------------------------------------------------------------------------------- 1 | package com.google.protobuf.gradle 2 | 3 | import groovy.transform.CompileDynamic 4 | import org.gradle.testkit.runner.BuildResult 5 | import org.gradle.testkit.runner.TaskOutcome 6 | import spock.lang.Specification 7 | import spock.lang.Unroll 8 | 9 | /** 10 | * Unit test confirming copy spec is explicitly defined for gradle7+ compliance. 11 | */ 12 | @CompileDynamic 13 | class ProtobufKotlinDslCopySpecTest extends Specification { 14 | private static final List GRADLE_VERSIONS = ["5.6", "6.0", "6.7.1", "7.0", "7.4.2"] 15 | 16 | @Unroll 17 | void "testProjectKotlinDslCopySpec should declare explicit copy spec [gradle #gradleVersion]"() { 18 | given: "project from testProjectKotlinDslCopySpec" 19 | File projectDir = ProtobufPluginTestHelper.projectBuilder('testProjectKotlinDslCopySpec') 20 | .copyDirs('testProjectKotlinDslCopySpec') 21 | .build() 22 | 23 | when: "build is invoked" 24 | BuildResult result = ProtobufPluginTestHelper.getGradleRunner( 25 | projectDir, 26 | gradleVersion, 27 | "test", 28 | "build" 29 | ).build() 30 | 31 | then: "it succeed" 32 | 33 | result.task(":test").outcome == TaskOutcome.SUCCESS 34 | 35 | verifyProjectDir(projectDir) 36 | 37 | where: 38 | gradleVersion << GRADLE_VERSIONS 39 | } 40 | 41 | private static void verifyProjectDir(File projectDir) { 42 | File generatedSrcDir = new File(projectDir.path, "build/generated/sources/proto/main/java") 43 | List fileList = [] 44 | generatedSrcDir.eachFileRecurse { file -> 45 | if (file.path.endsWith('.java')) { 46 | fileList.add (file) 47 | } 48 | } 49 | assert fileList.size > 0 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/test/groovy/com/google/protobuf/gradle/ProtobufKotlinDslPluginTest.groovy: -------------------------------------------------------------------------------- 1 | package com.google.protobuf.gradle 2 | 3 | import groovy.transform.CompileDynamic 4 | import org.gradle.testkit.runner.BuildResult 5 | import org.gradle.testkit.runner.GradleRunner 6 | import org.gradle.testkit.runner.TaskOutcome 7 | import spock.lang.Specification 8 | import spock.lang.Unroll 9 | 10 | /** 11 | * Unit tests for kotlin dsl extensions. 12 | */ 13 | @CompileDynamic 14 | class ProtobufKotlinDslPluginTest extends Specification { 15 | private static final List GRADLE_VERSIONS = ["5.6", "6.1.1", "6.5.1", "7.4.2"] 16 | private static final List ANDROID_PLUGIN_VERSION = ["3.5.0", "4.0.0", "4.1.0", "7.2.1"] 17 | 18 | @Unroll 19 | void "testProjectKotlinDsl should be successfully executed (java-only project) [gradle #gradleVersion]"() { 20 | given: "project from testProjectKotlinDslBase" 21 | File projectDir = ProtobufPluginTestHelper.projectBuilder('testProjectKotlinDsl') 22 | .copyDirs('testProjectKotlinDslBase') 23 | .build() 24 | 25 | when: "build is invoked" 26 | BuildResult result = GradleRunner.create() 27 | .withProjectDir(projectDir) 28 | .withArguments('build', '--stacktrace') 29 | .withPluginClasspath() 30 | .withGradleVersion(gradleVersion) 31 | .forwardStdOutput(new OutputStreamWriter(System.out)) 32 | .forwardStdError(new OutputStreamWriter(System.err)) 33 | // Enabling debug causes the test to fail. 34 | // https://github.com/gradle/gradle/issues/6862 35 | //.withDebug(true) 36 | .build() 37 | 38 | then: "it succeed" 39 | result.task(":build").outcome == TaskOutcome.SUCCESS 40 | ProtobufPluginTestHelper.verifyProjectDir(projectDir) 41 | 42 | where: 43 | gradleVersion << GRADLE_VERSIONS 44 | } 45 | 46 | @Unroll 47 | void "testProjectAndroidKotlinDsl should be successfully executed [android #agpVersion, gradle #gradleVersion]"() { 48 | given: "project from testProjectKotlinDsl" 49 | File testProjectAndroidKotlinDslStaging = ProtobufPluginTestHelper.projectBuilder('testProjectAndroidKotlinDsl') 50 | .copyDirs('testProjectAndroidKotlinDsl') 51 | .build() 52 | File testProjectLiteStaging = ProtobufPluginTestHelper.projectBuilder('testProjectLite') 53 | .copyDirs('testProjectLite') 54 | .build() 55 | File mainProjectDir = ProtobufPluginTestHelper.projectBuilder('testProjectAndroidDslMain') 56 | .copySubProjects(testProjectAndroidKotlinDslStaging, testProjectLiteStaging) 57 | .withAndroidPlugin(agpVersion) 58 | .build() 59 | 60 | when: "build is invoked" 61 | BuildResult result = ProtobufPluginTestHelper.getAndroidGradleRunner( 62 | mainProjectDir, 63 | gradleVersion, 64 | agpVersion, 65 | "testProjectAndroidKotlinDsl:build" 66 | ).build() 67 | 68 | then: "it succeed" 69 | result.task(":testProjectAndroidKotlinDsl:build").outcome == TaskOutcome.SUCCESS 70 | 71 | where: 72 | agpVersion << ANDROID_PLUGIN_VERSION 73 | gradleVersion << GRADLE_VERSIONS 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/test/groovy/com/google/protobuf/gradle/ToolsLocatorSpec.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Google Inc. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this 8 | * list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors 15 | * may be used to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | package com.google.protobuf.gradle 30 | 31 | import groovy.transform.CompileDynamic 32 | import spock.lang.Specification 33 | 34 | /** 35 | * Tests for ToolsLocator 36 | */ 37 | @CompileDynamic 38 | class ToolsLocatorSpec extends Specification { 39 | void 'test: `classifier` and `extension` should both be `null`'() { 40 | given: 41 | String input = 'com.example:example-plugin:0.0.0-rc0+experimental' 42 | 43 | expect: 44 | ['com.example', 'example-plugin', '0.0.0-rc0+experimental', null, null] == ToolsLocator.artifactParts(input) 45 | } 46 | 47 | void 'test: `classifier` should be parsed and `extension` should be null'() { 48 | given: 49 | String input = 'com.example:example-plugin:0.0.0-rc0+experimental:classifier' 50 | 51 | expect: 52 | ['com.example', 'example-plugin', '0.0.0-rc0+experimental', 'classifier', null] == ToolsLocator.artifactParts(input) 53 | } 54 | 55 | void 'test: `classifier` should be `null` and `extension` should be parsed'() { 56 | given: 57 | String input = 'com.example:example-plugin:0.0.0-rc0+experimental@extension' 58 | 59 | expect: 60 | ['com.example', 'example-plugin', '0.0.0-rc0+experimental', null, 'extension'] == ToolsLocator.artifactParts(input) 61 | } 62 | 63 | void 'test: `classifier` and `extension` should both be parsed'() { 64 | given: 65 | String input = 'com.example:example-plugin:0.0.0-rc0+experimental:classifier@extension' 66 | List expected = ['com.example', 'example-plugin', '0.0.0-rc0+experimental', 'classifier', 'extension'] 67 | 68 | expect: 69 | expected == ToolsLocator.artifactParts(input) 70 | } 71 | 72 | void 'test: empty extension should still be parsed as is'() { 73 | given: 74 | String input = 'com.example::example-plugin:0.0.0-rc0+experimental:classifier@' 75 | 76 | List expected = ['com.example', 'example-plugin', '0.0.0-rc0+experimental', 'classifier', ''] 77 | 78 | expect: 79 | expected == ToolsLocator.artifactParts(input) 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /testProject/build.gradle: -------------------------------------------------------------------------------- 1 | // This build is not a complete project, but is used to generate a project. 2 | // See: ProtobufPluginTestHelper.groovy 3 | plugins { 4 | id 'java' 5 | id 'idea' 6 | id 'eclipse' 7 | id 'com.google.protobuf' 8 | } 9 | apply from: 'build_base.gradle' 10 | -------------------------------------------------------------------------------- /testProject/src/main/java/Foo.java: -------------------------------------------------------------------------------- 1 | import com.google.protobuf.MessageLite; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Foo { 7 | public static List getDefaultInstances() { 8 | ArrayList list = new ArrayList(); 9 | // from src/main/proto/test.proto 10 | list.add(ws.antonov.protobuf.test.Test.TestMessage.getDefaultInstance()); 11 | list.add(ws.antonov.protobuf.test.Test.AnotherMessage.getDefaultInstance()); 12 | list.add(ws.antonov.protobuf.test.Test.Item.getDefaultInstance()); 13 | list.add(ws.antonov.protobuf.test.Test.DataMap.getDefaultInstance()); 14 | // from src/main/proto/sample.proto (java_multiple_files == true, thus no outter class) 15 | list.add(com.example.tutorial.Msg.getDefaultInstance()); 16 | list.add(com.example.tutorial.SecondMsg.getDefaultInstance()); 17 | // from lib/protos.tar.gz/stuff.proto 18 | list.add(Stuff.Blah.getDefaultInstance()); 19 | // from ext/more.proto 20 | list.add(More.MoreMsg.getDefaultInstance()); 21 | list.add(More.Foo.getDefaultInstance()); 22 | // from ext/test1.proto 23 | list.add(test1.Test1.Test1Msg.getDefaultInstance()); 24 | // from ext/ext1/test1.proto 25 | list.add(ext1.Ext1Test1.Ext1Test1Msg.getDefaultInstance()); 26 | // from ext/test2.proto 27 | list.add(test2.Test2.Test2Msg.getDefaultInstance()); 28 | return list; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /testProject/src/test/java/FooTest.java: -------------------------------------------------------------------------------- 1 | import static org.junit.Assert.assertEquals; 2 | import static org.junit.Assert.assertTrue; 3 | 4 | public class FooTest { 5 | @org.junit.Test 6 | public void testMainProtos() { 7 | assertEquals(12, Foo.getDefaultInstances().size()); 8 | } 9 | 10 | @org.junit.Test 11 | public void testTestProtos() { 12 | // from src/test/proto/test.proto 13 | Test.MsgTest.getDefaultInstance(); 14 | // from lib/protos-test.tar.gz 15 | test.Stuff.BlahTest.getDefaultInstance(); 16 | } 17 | 18 | @org.junit.Test 19 | public void testGrpc() { 20 | // from src/grpc/proto/ 21 | assertTrue(com.google.protobuf.GeneratedMessageV3.class.isAssignableFrom( 22 | io.grpc.testing.integration.Messages.SimpleRequest.class)); 23 | assertTrue(Object.class.isAssignableFrom(io.grpc.testing.integration.TestServiceGrpc.class)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /testProjectAndroid/build.gradle: -------------------------------------------------------------------------------- 1 | // This build is not a complete project, but is used to generate a project. 2 | // See: ProtobufPluginTestHelper.groovy 3 | 4 | plugins { 5 | id 'com.google.protobuf' 6 | } 7 | apply plugin: 'com.android.application' 8 | apply from: 'build_base.gradle' 9 | -------------------------------------------------------------------------------- /testProjectAndroid/src/androidTest/java/io/grpc/helloworldexample/TestLibrary.java: -------------------------------------------------------------------------------- 1 | package io.grpc.helloworldexample; 2 | 3 | public class TestLibrary { 4 | HelloworldActivity activity; 5 | 6 | // From src/androidTest/proto/sample.proto 7 | com.example.tutorial.Msg msg; 8 | 9 | // From src/main/proto/helloworld.proto 10 | Helloworld.HelloRequest request; 11 | 12 | // From dependency project (testProjectLite/testProjectAndroidLibrary): src/proto/messages.proto 13 | io.grpc.testing.Messages.SimpleRequest simpleRequest; 14 | 15 | // From lib/protos.jar 16 | com.google.protobuf.gradle.test.External.BlobMessage blobMessage; 17 | 18 | // TODO(zpencer): reflectively check that unit test protos are not visible 19 | // This requires figuring out how to get androidTest to run. Currently the sources in androidTest 20 | // are compiled, but test classes are not actually executed. 21 | 22 | TestLibrary() { 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /testProjectAndroid/src/main/java/io/grpc/helloworldexample/HelloworldActivity.java: -------------------------------------------------------------------------------- 1 | package io.grpc.helloworldexample; 2 | 3 | import android.content.Context; 4 | import android.os.AsyncTask; 5 | import android.os.Bundle; 6 | import android.support.v7.app.ActionBarActivity; 7 | import android.text.TextUtils; 8 | import android.view.View; 9 | import android.view.inputmethod.InputMethodManager; 10 | import android.widget.Button; 11 | import android.widget.EditText; 12 | import android.widget.TextView; 13 | 14 | import java.util.concurrent.TimeUnit; 15 | 16 | import io.grpc.ManagedChannel; 17 | import io.grpc.helloworldexample.Helloworld.HelloReply; 18 | import io.grpc.helloworldexample.Helloworld.HelloRequest; 19 | import io.grpc.okhttp.OkHttpChannelBuilder; 20 | 21 | public class HelloworldActivity extends ActionBarActivity { 22 | private Button mSendButton; 23 | private EditText mHostEdit; 24 | private EditText mPortEdit; 25 | private EditText mMessageEdit; 26 | private TextView mResultText; 27 | 28 | @Override 29 | protected void onCreate(Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | setContentView(R.layout.activity_helloworld); 32 | mSendButton = (Button) findViewById(R.id.send_button); 33 | mHostEdit = (EditText) findViewById(R.id.host_edit_text); 34 | mPortEdit = (EditText) findViewById(R.id.port_edit_text); 35 | mMessageEdit = (EditText) findViewById(R.id.message_edit_text); 36 | mResultText = (TextView) findViewById(R.id.grpc_response_text); 37 | } 38 | 39 | public void sendMessage(View view) { 40 | ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)) 41 | .hideSoftInputFromWindow(mHostEdit.getWindowToken(), 0); 42 | mSendButton.setEnabled(false); 43 | new GrpcTask().execute(); 44 | } 45 | 46 | private class GrpcTask extends AsyncTask { 47 | private String mHost; 48 | private String mMessage; 49 | private int mPort; 50 | private ManagedChannel mChannel; 51 | 52 | @Override 53 | protected void onPreExecute() { 54 | mHost = mHostEdit.getText().toString(); 55 | mMessage = mMessageEdit.getText().toString(); 56 | String portStr = mPortEdit.getText().toString(); 57 | mPort = TextUtils.isEmpty(portStr) ? 0 : Integer.valueOf(portStr); 58 | mResultText.setText(""); 59 | } 60 | 61 | private String sayHello(ManagedChannel channel) { 62 | GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel); 63 | HelloRequest message = HelloRequest.newBuilder().setName(mMessage).build(); 64 | HelloReply reply = stub.sayHello(message); 65 | return reply.getMessage(); 66 | } 67 | 68 | @Override 69 | protected String doInBackground(Void... nothing) { 70 | try { 71 | mChannel = OkHttpChannelBuilder.forAddress(mHost, mPort).build(); 72 | return sayHello(mChannel); 73 | } catch (Exception e) { 74 | 75 | return "Failed... : " + e.getMessage(); 76 | } 77 | } 78 | 79 | @Override 80 | protected void onPostExecute(String result) { 81 | try { 82 | mChannel.shutdown().awaitTermination(1, TimeUnit.SECONDS); 83 | } catch (InterruptedException e) { 84 | Thread.currentThread().interrupt(); 85 | } 86 | mResultText.setText(result); 87 | mSendButton.setEnabled(true); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /testProjectAndroid/src/test/java/io/grpc/helloworldexample/UnitTest.java: -------------------------------------------------------------------------------- 1 | package io.grpc.helloworldexample; 2 | 3 | import static org.junit.Assert.fail; 4 | 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.junit.runners.JUnit4; 8 | 9 | @RunWith(JUnit4.class) 10 | public final class UnitTest { 11 | private final HelloworldActivity activity = new HelloworldActivity(); 12 | // From src/test/proto/unittest.proto 13 | private com.example.tutorial.UnitTestMsg msg; 14 | 15 | // From src/main/proto/helloworld.proto 16 | private Helloworld.HelloRequest request; 17 | 18 | // From dependency project (testProjectLite/testProjectAndroidLibrary): src/proto/messages.proto 19 | private io.grpc.testing.Messages.SimpleRequest simpleRequest; 20 | 21 | // From lib/protos.jar 22 | private com.google.protobuf.gradle.test.External.BlobMessage blobMessage; 23 | 24 | @Test 25 | public void ensureAndroidTestProtosNotVisible() throws Exception { 26 | // we should not see the protos from src/androidTest/proto/ 27 | try { 28 | Class ignored = Class.forName("com.example.tutorial.Msg"); 29 | fail(); 30 | } catch (ClassNotFoundException expected){ 31 | // noop 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /testProjectAndroidBare/build_base.gradle: -------------------------------------------------------------------------------- 1 | android { 2 | compileSdkVersion 26 3 | buildToolsVersion "26.0.1" 4 | 5 | defaultConfig { 6 | applicationId "io.dont.build.me" 7 | minSdkVersion 7 8 | targetSdkVersion 23 9 | versionCode 1 10 | versionName "1.0" 11 | } 12 | 13 | compileOptions { 14 | sourceCompatibility = JavaVersion.VERSION_1_8 15 | targetCompatibility = JavaVersion.VERSION_1_8 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /testProjectAndroidBare/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /testProjectAndroidBase/lib/protos.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/protobuf-gradle-plugin/0cce976ae1fcb35f29ec67d418a52b8622105c67/testProjectAndroidBase/lib/protos.jar -------------------------------------------------------------------------------- /testProjectAndroidBase/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/thagikura/android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /testProjectAndroidBase/src/androidTest/proto/sample.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | option java_package = "com.example.tutorial"; 4 | option java_outer_classname = "OuterSample"; 5 | option java_multiple_files = true; 6 | 7 | // From the main sourceSet 8 | import "helloworld.proto"; 9 | // From tested variant's dependency testProjectLite: src/proto 10 | import "messages.proto"; 11 | 12 | message Msg { 13 | string foo = 1; 14 | SecondMsg blah = 2; 15 | } 16 | 17 | message SecondMsg { 18 | int32 blah = 1; 19 | // Uses message type from helloworld.proto 20 | helloworld.HelloReply reply = 2; 21 | // Uses message type from messages.proto 22 | grpc.testing.SimpleContext context = 3; 23 | } 24 | -------------------------------------------------------------------------------- /testProjectAndroidBase/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /testProjectAndroidBase/src/main/proto/README.md: -------------------------------------------------------------------------------- 1 | Hello World 2 | -------------------------------------------------------------------------------- /testProjectAndroidBase/src/main/proto/helloworld.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | syntax = "proto3"; 31 | 32 | // From testProject: src/nano/proto 33 | import "messages.proto"; 34 | 35 | option java_package = "io.grpc.helloworldexample"; 36 | 37 | package helloworld; 38 | 39 | // The greeting service definition. 40 | service Greeter { 41 | // Sends a greeting 42 | rpc SayHello (HelloRequest) returns (HelloReply) {} 43 | } 44 | 45 | // The request message containing the user's name. 46 | message HelloRequest { 47 | string name = 1; 48 | // Uses message type from messages.proto 49 | grpc.testing.SimpleContext context = 2; 50 | } 51 | 52 | // The response message containing the greetings 53 | message HelloReply { 54 | string message = 1; 55 | } 56 | -------------------------------------------------------------------------------- /testProjectAndroidBase/src/main/res/layout/activity_helloworld.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 17 | 24 | 25 | 26 | 27 | 32 | 33 |