Protocol Buffers - Google's data interchange format (grpc依赖)
https://developers.google.com/protocol-buffers/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
5.3 KiB
139 lines
5.3 KiB
1 year ago
|
# Prototiller Requirements for Editions
|
||
|
|
||
|
**Author:** [@mcy](https://github.com/mcy)
|
||
|
|
||
|
**Approved:** 2022-11-29
|
||
|
|
||
|
## Background
|
||
|
|
||
|
Prototiller is Protobuf's new mass refactoring Swiss army knife, similar to
|
||
|
Buildozer. We plan to use Prototiller to enable LSCs within google3 and to allow
|
||
|
users (internal and external) to modify `.proto` files safely.
|
||
|
|
||
|
Prototiller is being developed as part of the
|
||
|
[Editions](../editions/what-are-protobuf-editions.md) project, and will
|
||
|
prioritize enabling Editions-related refactorings to unblock Editions migrations
|
||
|
in 2023. This document describes the relevant requirements.
|
||
|
|
||
|
## Overview
|
||
|
|
||
|
*Protochangifier Semantic Actions* (not available externally) describes the
|
||
|
original design for the Prototiller interface; it would consume a Protobuf
|
||
|
message that described changes to apply to a `.proto` file passed as input. In
|
||
|
this document, we prescribe a variant of this interface that fulfills *only* the
|
||
|
needs of Editions, while remaining extensible for future change actions.
|
||
|
|
||
|
Broad requirements are as follows:
|
||
|
|
||
|
* Actions must include the following Editions-oriented upgrade workflows:
|
||
|
* Upgrade a file to a particular edition, regardless of whether it's in
|
||
|
syntax mode or editions mode, updating features in such a way to be a
|
||
|
no-op. **This is the highest-priority workflow.**
|
||
|
* "Clean up" features in a particular file: i.e., run a simple algorithm
|
||
|
to determine the smallest set of features that need to be present at
|
||
|
each level of the file.
|
||
|
* Modify features from a particular syntax element.
|
||
|
* Actions must be both specific to particular syntax elements (for when change
|
||
|
specs are checked in alongside `.proto` files by Schema Consumers), and
|
||
|
generic (so that a single change spec or set of change specs can power a
|
||
|
large-scale change).
|
||
|
|
||
|
In this document we provide a recommendation for a Protobuf schema based on the
|
||
|
original Protochangifier design, but geared towards these specific needs.
|
||
|
|
||
|
This is only a recommendation; the Prototiller project owners should modify this
|
||
|
to suit the implementation; only the requirements in this document are binding,
|
||
|
and the schema is merely an illustration of those requirements.
|
||
|
|
||
|
The suggested schema is as follows.
|
||
|
|
||
|
```
|
||
|
syntax = "proto2";
|
||
|
|
||
|
package prototiller;
|
||
|
|
||
|
// This is the proto that Prototiller accepts as input.
|
||
|
message ChangeSpec {
|
||
|
// Actions to execute on the file.
|
||
|
repeated Action actions = 1;
|
||
|
|
||
|
// Some changes may result in a wireformat break; changing field type is
|
||
|
// usually unsafe. By default, Prototiller does not allow such changes,
|
||
|
// users can set allow_unsafe_wire_format_changes to true to force the change.
|
||
|
optional bool allow_unsafe_wire_format_changes = 2 [default = false];
|
||
|
optional bool allow_unsafe_text_format_changes = 3 [default = false];
|
||
|
optional bool allow_unsafe_json_format_changes = 4 [default = false];
|
||
|
}
|
||
|
|
||
|
// A single action. See messages below for description of their
|
||
|
// semantics.
|
||
|
message Action {
|
||
|
oneof kind {
|
||
|
UpgradeEdition upgrade_edition = 20;
|
||
|
CleanUpFeatures clean_up_features = 21;
|
||
|
ModifyFeature modify_feature = 22;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Upgrades the edition of a file to a specified edition.
|
||
|
// Treats syntax mode as being a weird, special edition that cannot be
|
||
|
// upgraded to.
|
||
|
//
|
||
|
// This action is always safe.
|
||
|
message UpgradeEdition {
|
||
|
// The edition to upgrade to.
|
||
|
optional string edition = 1;
|
||
|
}
|
||
|
|
||
|
// Cleans up features in a file, such that there are as few explicitly set
|
||
|
// features as necessary.
|
||
|
//
|
||
|
// This action is always safe.
|
||
|
message CleanUpFeatures {}
|
||
|
|
||
|
// Modifies a specific feature on all syntax elements that match and which can
|
||
|
// host that particular feature.
|
||
|
//
|
||
|
// Prototiller must be aware of which changes affect wire format, so that it
|
||
|
// can flag them as unsafe.
|
||
|
message ModifyFeature {
|
||
|
// The name of the feature to modify.
|
||
|
repeated proto2.UninterpretedOption.NamePart feature = 1;
|
||
|
|
||
|
// A pattern for matching paths to syntax elements to modify.
|
||
|
//
|
||
|
// Elements of this field can either be identifiers, or the string "*", which
|
||
|
// matches all identifiers. Thus, ["foo", "Bar"] matches the message foo.Bar,
|
||
|
// ["foo", "Bar", "*"] matches all fields and nested types of foo.Bar
|
||
|
// (recursively), and ["*"] matches all elements of a file.
|
||
|
repeated string path_pattern = 2;
|
||
|
|
||
|
// The value to set the feature to. If not set, this means that the
|
||
|
// feature should be deleted.
|
||
|
oneof value {
|
||
|
int64 int_value = 20;
|
||
|
double double_value = 21;
|
||
|
// ... and so on.
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## Alternatives Considered
|
||
|
|
||
|
This document does not capture a design so much as requirements that a design
|
||
|
must satisfy, so we will be brief on potential alternatives to the requirements,
|
||
|
and why we decided against them.
|
||
|
|
||
|
* Omit feature cleanup as its own action, and let it happen implicitly as part
|
||
|
of other actions.
|
||
|
* It is desirable to be able to aggressively run this operation
|
||
|
everywhere, potentially even as part of "format on save" in Cider and
|
||
|
other IDEs.
|
||
|
* Make `ModifyFeature` operate on all syntax elements of a file
|
||
|
simultaneously.
|
||
|
* `ModifyFeature` is intended so that SchemaConsumers can affect
|
||
|
fine-grained control of features in `.proto` files they import. Users
|
||
|
will want to be able to wipe out a feature from all fields in a file, or
|
||
|
perhaps just on a handful of fields they care about. Offering simple
|
||
|
pattern-matching supports both.
|