WireRun

class WireRun(val sourcePath: List<Location>, val protoPath: List<Location> = listOf(), val treeShakingRoots: List<String> = listOf("*"), val treeShakingRubbish: List<String> = listOf(), val moves: List<TypeMover.Move> = listOf(), val sinceVersion: String? = null, val untilVersion: String? = null, val onlyVersion: String? = null, val targets: List<Target>, val modules: Map<String, WireRun.Module> = emptyMap(), val permitPackageCycles: Boolean = false, val escapeKotlinKeywords: Boolean = false, val eventListeners: List<EventListener> = listOf(), val rejectUnusedRootsOrPrunes: Boolean = true, val opaqueTypes: List<String> = listOf())

An invocation of the Wire compiler. Each invocation performs the following operations:

  1. Read source .proto files directly from the file system or from archive files (ie. .jar and .zip files). This will also load imported .proto files from either the sourcePath or protoPath. The collection of loaded type declarations is called a schema.

  2. Validate the schema and resolve references between types.

  3. Optionally refactor the schema. This builds a new schema that is a subset of the original. The new schema contains only types that are both transitively reachable from treeShakingRoots and not in treeShakingRubbish. Types are moved to different files as specified by moves.

  4. Call each target. It will generate sources for protos in the sourcePath that are in its Target.includes, that are not in its Target.excludes, and that haven't already been emitted by an earlier target.

Source Directories and Archives

-------------------------------

The sourcePath and protoPath lists contain locations that are of the following forms:

  • Locations of .proto files.

  • Locations of directories that contain a tree of .proto files. Typically this is a directory ending in src/main/proto.

  • Locations of .zip and .jar archives that contain a tree of .proto files. Typically this is a .jar file from a Maven repository.

When one .proto message imports another, the import is resolved from the base of each location and archive. If the build is in the unfortunate situation where an import could be resolved by multiple files, whichever was listed first takes precedence.

Although the content and structure of sourcePath and protoPath are the same, only types defined in sourcePath are used to generate sources.

Matching Packages, Types, and Members

-------------------------------------

The treeShakingRoots, treeShakingRubbish, Target.includes and Target.excludes lists contain strings that select proto types and members. Strings in these lists are in one of these forms:

  • Package names followed by .*, like squareup.dinosaurs.*. This matches types defined in the package and its descendant packages. A lone asterisk * matches all packages.

  • Fully-qualified type names like squareup.dinosaurs.Dinosaur. Types may be messages, enums, or services.

  • Fully-qualified member names like squareup.dinosaurs.Dinosaur#name. These are type names followed by # followed by a member name. Members may be message fields, enum constants, or service RPCs.

It is an error to specify mutually-redundant values in any of these lists. For example, the list [squareup.dinosaurs, squareup.dinosaurs.Dinosaur] is invalid because the second element is already matched by the first.

Every element in each lists must apply to at least one declaration. Otherwise that option is unnecessary and a possible typo.

Composability

-------------

There are many moving parts in this system! For most applications it is safe to use sourcePath and targets only. The other options are for the benefit of large and modular applications.

Use protoPath when one proto module depends on another proto module.

These .proto files are used for checking dependencies only. It is assumed that the sources for these protos are generated elsewhere.

Use tree shaking to remove unwanted types.

Tree shaking can be used to create a small-as-possible generated footprint even if the source declarations are large. This works like ProGuard and other code shrinking compilers: it allows you to benefit from a shared codebase without creating a large artifact.

Use multiple targets to split generated code across multiple programming languages.

If your project is already using generated Java, it’s difficult to switch to generated Kotlin. Instead of switching everything over at once you can use multiple targets to switch over incrementally. Targets consume their types; subsequent targets get whatever types are left over.

Constructors

Link copied to clipboard
constructor(sourcePath: List<Location>, protoPath: List<Location> = listOf(), treeShakingRoots: List<String> = listOf("*"), treeShakingRubbish: List<String> = listOf(), moves: List<TypeMover.Move> = listOf(), sinceVersion: String? = null, untilVersion: String? = null, onlyVersion: String? = null, targets: List<Target>, modules: Map<String, WireRun.Module> = emptyMap(), permitPackageCycles: Boolean = false, escapeKotlinKeywords: Boolean = false, eventListeners: List<EventListener> = listOf(), rejectUnusedRootsOrPrunes: Boolean = true, opaqueTypes: List<String> = listOf())

Types

Link copied to clipboard
data class Module(val dependencies: Set<String> = emptySet(), val pruningRules: PruningRules? = null)

Properties

Link copied to clipboard

If true, Kotlin keywords are escaped with backticks. If false, an underscore is added as a suffix.

Link copied to clipboard
Link copied to clipboard

A map from module dir to module info which dictates how the loaded types are partitioned and generated.

Link copied to clipboard
val moves: List<TypeMover.Move>

Types to move before generating code or producing other output. Use this with ProtoTarget to refactor proto schemas safely.

Link copied to clipboard
val onlyVersion: String? = null

The only version of the version range. Fields with until values greater than this, as well as fields with since values less than or equal to this, are retained. This field is mutually exclusive with sinceVersion and untilVersion.

Link copied to clipboard

All qualified named Protobuf types in opaqueTypes will be evaluated as being of type bytes. On code generation, the fields of such types will be using the platform equivalent of bytes, like okio.ByteString for the JVM. Note that scalar types cannot be opaqued. The opaque step will happen before the tree shaking one.

Link copied to clipboard

If true, no validation will be executed to check package cycles.

Link copied to clipboard

Sources .proto files for this task to use when resolving references.

Link copied to clipboard

If true, Wire will fail if not all treeShakingRoots and treeShakingRubbish are used when tree-shaking the schema. This can help discover incorrect configurations early and avoid misexpectations about the built schema.

Link copied to clipboard
val sinceVersion: String? = null

The exclusive lower bound of the version range. Fields with until values greater than this are retained.

Link copied to clipboard

Source .proto files for this task to generate from.

Link copied to clipboard

Action to take with the loaded, resolved, and possibly-pruned schema.

Link copied to clipboard

The roots of the schema model. Wire will prune the schema model to only include types in this list and the types transitively required by them.

Link copied to clipboard

Types and members that will be stripped from the schema model. Wire will remove the elements themselves and also all references to them.

Link copied to clipboard
val untilVersion: String? = null

The inclusive upper bound of the version range. Fields with since values less than or equal to this are retained.

Functions

Link copied to clipboard
fun execute(fs: FileSystem, logger: WireLogger)