build method

  1. @override
Future<void> build(
  1. BuildStep buildStep
)

Generates the outputs for a given BuildStep.

Implementation

@override
Future<void> build(BuildStep buildStep) async {
  // When "useInstalledProtoc", we will not fetch any external resources
  final protoc = useInstalledProtoc
      ? File('protoc')
      : await fetchProtoc(protobufVersion);
  final protocPlugin = useInstalledProtoc
      ? File('')
      : await fetchProtocPlugin(protocPluginVersion, precompileProtocPlugin);

  final inputPath = path.normalize(buildStep.inputId.path);

  final pluginParameters = grpcEnabled ? 'grpc:' : '';

  // Read the input path to signal to the build graph that if the file changes
  // then it should be rebuilt.
  await buildStep.readAsString(buildStep.inputId);
  // Create the output directory (if necessary)
  await Directory(outputDirectory).create(recursive: true);
  // And run the "protoc" process
  await ProcessExtensions.runSafely(
    protoc.path,
    collectProtocArguments(protocPlugin, pluginParameters, inputPath),
  );

  // Just as with the read, the build runner spies on what we write, so we
  // need to write each output file explicitly, even though they've already
  // been written by protoc. This will ensure that if an output file is
  // deleted, a future build will recreate it. This also checks that the files
  // we were expected to write were actually written, since this will fail if
  // an output file wasn't created by protoc.
  await Future.wait(buildStep.allowedOutputs.map((AssetId out) async {
    var file = loadOutputFile(out);
    // When there is no service definition in a .proto file, the respective
    // .pbgrpc.dart file is not generated. So, we will tolerate its absence.
    if (file.path.endsWith('.pbgrpc.dart') && !await file.exists()) {
      return;
    }
    await buildStep.writeAsBytes(out, file.readAsBytes());
  }));
}