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.
138 lines
5.3 KiB
138 lines
5.3 KiB
# 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.
|
|
|