Protobuf Gradle Plugin

repository·master·Indexed 23 days ago

https://github.com/google/protobuf-gradle-plugin

A Gradle plugin that automates the compilation of Protocol Buffer (.proto) files by managing the protoc compiler and integrating generated source code into Java or Android build processes. It supports code generation for various languages, custom source directories, descriptor set generation, and integration with the lite runtime for Android.

Tokens
2.8K
Snippets
11
Records
17
Agent score
33%

What's inside protobuf-gradle-plugin

  1. How the Protobuf Gradle plugin works

    master

    The plugin automates two primary tasks:

    1. Code Generation: It assembles the Protobuf Compiler (protoc) command line to generate source files (e.g., Java) from your .proto files.
    2. Source Integration: It automatically adds the generated Java source files to the corresponding compilation unit (the sourceSet in Java projects or the variant in Android projects).

    Note: If you are generating non-Java/Kotlin source files, they are not automatically included in the compilation process. You must manually add them to your language-specific source sets.

  2. Use Protos from dependencies

    master

    You can include proto files from external dependencies in two ways:

    1. implementation configuration: Proto files are extracted to extracted-include-protos and added to the --proto_path flag. They are not re-compiled; they are treated as imports for your local protos.

      • Use this for upstream jars containing protos you want to import.
    2. protobuf configuration: Proto files are extracted to extracted-protos and added to the protoc command line as files to be compiled alongside your local files.

      • Use this for local packages, tarballs, or specific protobuf artifacts.
      • Note: Do not use fileTree() with the protobuf configuration.
  3. Customize code generation tasks with generateProtoTasks

    master

    The plugin generates a task for each protoc run. To configure these tasks (e.g., to add plugins or change output options), you must use the generateProtoTasks block.

    Important Rules:

    • DO NOT assume task names; they may change.
    • DO NOT configure tasks outside of the generateProtoTasks block due to timing constraints.

    Available selectors within generateProtoTasks:

    • all(): All protoc tasks.
    • ofSourceSet('name'): (Java-only) Tasks for a specific sourceSet.
    • ofFlavor('name'): (Android-only) Tasks for a flavor.
    • ofBuildType('name'): (Android-only) Tasks for a buildType.
    • ofVariant('name'): (Android-only) Tasks for a variant.
    • ofNonTest(): Non-androidTest tasks.
    • ofTest(): androidTest tasks.
  4. Add the Protobuf Gradle plugin to your project

    master

    To use the Protobuf plugin in a Gradle project using the Groovy DSL, add the plugin to your plugins block. The latest stable version is 0.10.0, which requires at least Gradle 7.6 and Java 11.

    plugins {
      id "com.google.protobuf" version "0.10.0"
    }
  5. Install the development version of the plugin

    master

    To use the latest development (SNAPSHOT) version, build the plugin locally and configure your project to look in mavenLocal().

    1. Build the plugin locally:
    ./gradlew publishToMavenLocal -x test
    1. In your project's settings.gradle, ensure mavenLocal() is in the pluginManagement repositories:
    pluginManagement {
      repositories {
        gradlePluginPortal()
        mavenLocal()
      }
    }
    1. In your project's build.gradle, apply the snapshot version:
    plugins {
      id "com.google.protobuf" version "0.10.1-SNAPSHOT"
    }
  6. Configure IntelliJ IDEA to use Gradle for builds

    master

    To ensure that Protobuf code generation occurs correctly before the compilation step, you must configure IntelliJ IDEA to delegate build and run actions to Gradle. If this is not enabled, IntelliJ will use its own internal build mechanism, which may bypass the plugin's code generation process.

    This plugin automatically integrates with the idea plugin to register .proto files and generated Java code as project sources.

    Settings -> Build, Execution, Deployment
      -> Build Tools -> Gradle -> Runner
      -> Delegate IDE build/run actions to gradle.
  7. Configure Protobuf Lite for Android

    master

    For Android, the lite runtime is recommended. Depending on your Protobuf version, the setup differs:

    For Protobuf 3.0.x through 3.7.x: Lite generation is a separate plugin (protobuf-lite).

    For Protobuf 3.8.0 and later: Lite generation is built into the java builtin via an option.

    // Protobuf 3.8.0+ approach
    dependencies {
      implementation 'com.google.protobuf:protobuf-javalite:3.8.0'
    }
    
    protobuf {
      protoc {
        artifact = 'com.google.protobuf:protoc:3.8.0'
      }
      generateProtoTasks {
        all().configureEach { task ->
          task.builtins {
            java {
              option "lite"
            }
          }
        }
      }
    }
  8. Locate the protoc executable

    master
    The plugin searches for the protoc executable in your system's PATH by default. However, it is recommended to use pre-compiled protoc artifacts from Maven Central. You can specify an artifact to download it automatically or a path to use a local installation. If multiple assignments are made in the protoc block, the last one wins.
  9. Generate descriptor set files

    master

    You can configure protoc to generate a descriptor_set.desc file. This is useful for tools that need to inspect the compiled proto definitions. Options include:

    • generateDescriptorSet = true: Enables generation.
    • descriptorSetOptions.path: Overrides the default location.
    • descriptorSetOptions.includeSourceInfo = true: Includes line numbers and comments.
    • descriptorSetOptions.includeImports = true: Makes the set self-contained by including all transitive imports.
    protobuf {
      generateProtoTasks {
        all().configureEach { task ->
          task.generateDescriptorSet = true
          task.descriptorSetOptions.path = "${projectDir}/build/descriptors/${task.sourceSet.name}.dsc"
          task.descriptorSetOptions.includeSourceInfo = true
          task.descriptorSetOptions.includeImports = true
        }
      }
    }
  10. Configure Protobuf code generation plugins

    master

    You can define codegen plugins (like grpc) in the protobuf.plugins block. This allows you to specify a downloadable artifact or a local path.

    Note: Defining a plugin here only locates it. To actually apply the plugin to your build, you must configure the specific tasks in the generateProtoTasks block.

    protobuf {
      plugins {
        // Locate a plugin named 'grpc'
        grpc {
          artifact = 'io.grpc:protoc-gen-grpc-java:1.0.0-pre2'
        }
      }
    }
  11. Customize Protobuf source directories

    master

    The plugin adds a proto source set to every Gradle sourceSet (or Android variant). By default, it looks for *.proto files in src/$sourceSetName/proto. You can customize these directories using the standard Gradle sourceSets syntax.

    For Java projects: Use the top-level sourceSet block.

    For Android projects: Use the android.sourceSets block.

    // Java project example
    sourceSets {
      main {
        proto {
          srcDir 'src/main/protobuf'
          include '**/*.protodevel'
        }
      }
    }
    
    // Android project example
    android {
      sourceSets {
        main {
          proto {
            srcDir 'src/main/proto'
          }
        }
      }
    }