diff --git a/Cargo.toml b/Cargo.toml index 5d96b78..f8717f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,3 +22,7 @@ members = [ "tests/compression", "tonic-web/tests/integration", ] + +[patch.crates-io] +prost-build = { git = "https://github.com/tokio-rs/prost/", branch = "lucio/format" } + diff --git a/tonic-build/Cargo.toml b/tonic-build/Cargo.toml index b210221..d75f9f3 100644 --- a/tonic-build/Cargo.toml +++ b/tonic-build/Cargo.toml @@ -17,7 +17,7 @@ version = "0.8.2" [dependencies] prettyplease = { version = "0.1" } proc-macro2 = "1.0" -prost-build = { version = "0.11", optional = true } +prost-build = { version = "0.11.1", optional = true } quote = "1.0" syn = "1.0" diff --git a/tonic-build/src/client.rs b/tonic-build/src/client.rs index 48d4551..3442ab8 100644 --- a/tonic-build/src/client.rs +++ b/tonic-build/src/client.rs @@ -12,13 +12,14 @@ pub fn generate( emit_package: bool, proto_path: &str, compile_well_known_types: bool, + build_transport: bool, attributes: &Attributes, ) -> TokenStream { let service_ident = quote::format_ident!("{}Client", service.name()); let client_mod = quote::format_ident!("{}_client", naive_snake_case(service.name())); let methods = generate_methods(service, emit_package, proto_path, compile_well_known_types); - let connect = generate_connect(&service_ident); + let connect = generate_connect(&service_ident, build_transport); let service_doc = generate_doc_comments(service.comment()); let package = if emit_package { service.package() } else { "" }; @@ -109,8 +110,8 @@ pub fn generate( } #[cfg(feature = "transport")] -fn generate_connect(service_ident: &syn::Ident) -> TokenStream { - quote! { +fn generate_connect(service_ident: &syn::Ident, enabled: bool) -> TokenStream { + let connect_impl = quote! { impl #service_ident { /// Attempt to create a new client by connecting to a given endpoint. pub async fn connect(dst: D) -> Result @@ -122,11 +123,17 @@ fn generate_connect(service_ident: &syn::Ident) -> TokenStream { Ok(Self::new(conn)) } } + }; + + if enabled { + connect_impl + } else { + TokenStream::new() } } #[cfg(not(feature = "transport"))] -fn generate_connect(_service_ident: &syn::Ident) -> TokenStream { +fn generate_connect(_service_ident: &syn::Ident, _enabled: bool) -> TokenStream { TokenStream::new() } diff --git a/tonic-build/src/lib.rs b/tonic-build/src/lib.rs index 66d3bf2..458e81c 100644 --- a/tonic-build/src/lib.rs +++ b/tonic-build/src/lib.rs @@ -213,6 +213,14 @@ fn generate_attributes<'a>( // Generate a singular line of a doc comment fn generate_doc_comment>(comment: S) -> TokenStream { + let comment = comment.as_ref(); + + let comment = if !comment.starts_with(" ") { + format!(" {}", comment) + } else { + comment.to_string() + }; + let mut doc_stream = TokenStream::new(); doc_stream.append(Ident::new("doc", Span::call_site())); diff --git a/tonic-build/src/manual.rs b/tonic-build/src/manual.rs index 90cb95a..3e9e4c8 100644 --- a/tonic-build/src/manual.rs +++ b/tonic-build/src/manual.rs @@ -367,6 +367,7 @@ impl ServiceGenerator { true, // emit_package, "", // proto_path, -- not used false, // compile_well_known_types, -- not used + self.builder.build_transport, &Attributes::default(), ); self.clients.extend(client); @@ -409,6 +410,7 @@ impl ServiceGenerator { pub struct Builder { build_server: bool, build_client: bool, + build_transport: bool, out_dir: Option, } @@ -418,6 +420,7 @@ impl Default for Builder { Self { build_server: true, build_client: true, + build_transport: true, out_dir: None, } } @@ -445,6 +448,15 @@ impl Builder { self } + /// Enable or disable generated clients and servers to have built-in tonic + /// transport features. + /// + /// When the `transport` feature is disabled this does nothing. + pub fn build_transport(mut self, enable: bool) -> Self { + self.build_transport = enable; + self + } + /// Set the output directory to generate code to. /// /// Defaults to the `OUT_DIR` environment variable. diff --git a/tonic-build/src/prost.rs b/tonic-build/src/prost.rs index b6b5bf1..69573e3 100644 --- a/tonic-build/src/prost.rs +++ b/tonic-build/src/prost.rs @@ -15,6 +15,7 @@ pub fn configure() -> Builder { Builder { build_client: true, build_server: true, + build_transport: true, file_descriptor_set_path: None, out_dir: None, extern_path: Vec::new(), @@ -172,6 +173,7 @@ impl prost_build::ServiceGenerator for ServiceGenerator { self.builder.emit_package, &self.builder.proto_path, self.builder.compile_well_known_types, + self.builder.build_transport, &self.builder.client_attributes, ); self.clients.extend(client); @@ -214,6 +216,7 @@ impl prost_build::ServiceGenerator for ServiceGenerator { pub struct Builder { pub(crate) build_client: bool, pub(crate) build_server: bool, + pub(crate) build_transport: bool, pub(crate) file_descriptor_set_path: Option, pub(crate) extern_path: Vec<(String, String)>, pub(crate) field_attributes: Vec<(String, String)>, @@ -243,6 +246,15 @@ impl Builder { self } + /// Enable or disable generated clients and servers to have built-in tonic + /// transport features. + /// + /// When the `transport` feature is disabled this does nothing. + pub fn build_transport(mut self, enable: bool) -> Self { + self.build_transport = enable; + self + } + /// Generate a file containing the encoded `prost_types::FileDescriptorSet` for protocol buffers /// modules. This is required for implementing gRPC Server Reflection. pub fn file_descriptor_set_path(mut self, path: impl AsRef) -> Self { diff --git a/tonic-build/src/server.rs b/tonic-build/src/server.rs index 48dd6ef..b026b4d 100644 --- a/tonic-build/src/server.rs +++ b/tonic-build/src/server.rs @@ -173,7 +173,7 @@ fn generate_trait( ) -> TokenStream { let methods = generate_trait_methods(service, proto_path, compile_well_known_types); let trait_doc = generate_doc_comment(&format!( - "Generated trait containing gRPC methods that should be implemented for use with {}Server.", + " Generated trait containing gRPC methods that should be implemented for use with {}Server.", service.name() )); @@ -219,7 +219,7 @@ fn generate_trait_methods( (false, true) => { let stream = quote::format_ident!("{}Stream", method.identifier()); let stream_doc = generate_doc_comment(&format!( - "Server streaming response type for the {} method.", + " Server streaming response type for the {} method.", method.identifier() )); @@ -235,7 +235,7 @@ fn generate_trait_methods( (true, true) => { let stream = quote::format_ident!("{}Stream", method.identifier()); let stream_doc = generate_doc_comment(&format!( - "Server streaming response type for the {} method.", + " Server streaming response type for the {} method.", method.identifier() )); diff --git a/tonic-health/src/generated/grpc.health.v1.rs b/tonic-health/src/generated/grpc.health.v1.rs index c5bd71f..22f73b3 100644 --- a/tonic-health/src/generated/grpc.health.v1.rs +++ b/tonic-health/src/generated/grpc.health.v1.rs @@ -1,16 +1,26 @@ #[derive(Clone, PartialEq, ::prost::Message)] pub struct HealthCheckRequest { - #[prost(string, tag="1")] + #[prost(string, tag = "1")] pub service: ::prost::alloc::string::String, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct HealthCheckResponse { - #[prost(enumeration="health_check_response::ServingStatus", tag="1")] + #[prost(enumeration = "health_check_response::ServingStatus", tag = "1")] pub status: i32, } /// Nested message and enum types in `HealthCheckResponse`. pub mod health_check_response { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum ServingStatus { Unknown = 0, @@ -103,8 +113,8 @@ pub mod health_client { self.inner = self.inner.accept_compressed(encoding); self } - ///If the requested service is unknown, the call will fail with status - ///NOT_FOUND. + /// If the requested service is unknown, the call will fail with status + /// NOT_FOUND. pub async fn check( &mut self, request: impl tonic::IntoRequest, @@ -124,21 +134,21 @@ pub mod health_client { ); self.inner.unary(request.into_request(), path, codec).await } - ///Performs a watch for the serving status of the requested service. - ///The server will immediately send back a message indicating the current - ///serving status. It will then subsequently send a new message whenever - ///the service's serving status changes. + /// Performs a watch for the serving status of the requested service. + /// The server will immediately send back a message indicating the current + /// serving status. It will then subsequently send a new message whenever + /// the service's serving status changes. /// - ///If the requested service is unknown when the call is received, the - ///server will send a message setting the serving status to - ///SERVICE_UNKNOWN but will *not* terminate the call. If at some - ///future point, the serving status of the service becomes known, the - ///server will send a new message with the service's serving status. + /// If the requested service is unknown when the call is received, the + /// server will send a message setting the serving status to + /// SERVICE_UNKNOWN but will *not* terminate the call. If at some + /// future point, the serving status of the service becomes known, the + /// server will send a new message with the service's serving status. /// - ///If the call terminates with status UNIMPLEMENTED, then clients - ///should assume this method is not supported and should not retry the - ///call. If the call terminates with any other status (including OK), - ///clients should retry the call with appropriate exponential backoff. + /// If the call terminates with status UNIMPLEMENTED, then clients + /// should assume this method is not supported and should not retry the + /// call. If the call terminates with any other status (including OK), + /// clients should retry the call with appropriate exponential backoff. pub async fn watch( &mut self, request: impl tonic::IntoRequest, @@ -167,36 +177,36 @@ pub mod health_client { pub mod health_server { #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; - ///Generated trait containing gRPC methods that should be implemented for use with HealthServer. + /// Generated trait containing gRPC methods that should be implemented for use with HealthServer. #[async_trait] pub trait Health: Send + Sync + 'static { - ///If the requested service is unknown, the call will fail with status - ///NOT_FOUND. + /// If the requested service is unknown, the call will fail with status + /// NOT_FOUND. async fn check( &self, request: tonic::Request, ) -> Result, tonic::Status>; - ///Server streaming response type for the Watch method. + /// Server streaming response type for the Watch method. type WatchStream: futures_core::Stream< Item = Result, > + Send + 'static; - ///Performs a watch for the serving status of the requested service. - ///The server will immediately send back a message indicating the current - ///serving status. It will then subsequently send a new message whenever - ///the service's serving status changes. + /// Performs a watch for the serving status of the requested service. + /// The server will immediately send back a message indicating the current + /// serving status. It will then subsequently send a new message whenever + /// the service's serving status changes. /// - ///If the requested service is unknown when the call is received, the - ///server will send a message setting the serving status to - ///SERVICE_UNKNOWN but will *not* terminate the call. If at some - ///future point, the serving status of the service becomes known, the - ///server will send a new message with the service's serving status. + /// If the requested service is unknown when the call is received, the + /// server will send a message setting the serving status to + /// SERVICE_UNKNOWN but will *not* terminate the call. If at some + /// future point, the serving status of the service becomes known, the + /// server will send a new message with the service's serving status. /// - ///If the call terminates with status UNIMPLEMENTED, then clients - ///should assume this method is not supported and should not retry the - ///call. If the call terminates with any other status (including OK), - ///clients should retry the call with appropriate exponential backoff. + /// If the call terminates with status UNIMPLEMENTED, then clients + /// should assume this method is not supported and should not retry the + /// call. If the call terminates with any other status (including OK), + /// clients should retry the call with appropriate exponential backoff. async fn watch( &self, request: tonic::Request, diff --git a/tonic-types/src/generated/google.rpc.rs b/tonic-types/src/generated/google.rpc.rs index 6843e36..1937ae2 100644 --- a/tonic-types/src/generated/google.rpc.rs +++ b/tonic-types/src/generated/google.rpc.rs @@ -8,16 +8,16 @@ #[derive(Clone, PartialEq, ::prost::Message)] pub struct Status { /// The status code, which should be an enum value of \\[google.rpc.Code\]\[google.rpc.Code\\]. - #[prost(int32, tag="1")] + #[prost(int32, tag = "1")] pub code: i32, /// A developer-facing error message, which should be in English. Any /// user-facing error message should be localized and sent in the /// \\[google.rpc.Status.details\]\[google.rpc.Status.details\\] field, or localized by the client. - #[prost(string, tag="2")] + #[prost(string, tag = "2")] pub message: ::prost::alloc::string::String, /// A list of messages that carry the error details. There is a common set of /// message types for APIs to use. - #[prost(message, repeated, tag="3")] + #[prost(message, repeated, tag = "3")] pub details: ::prost::alloc::vec::Vec<::prost_types::Any>, } /// Describes when the clients can retry a failed request. Clients could ignore @@ -36,17 +36,17 @@ pub struct Status { #[derive(Clone, PartialEq, ::prost::Message)] pub struct RetryInfo { /// Clients should wait at least this long between retrying the same request. - #[prost(message, optional, tag="1")] + #[prost(message, optional, tag = "1")] pub retry_delay: ::core::option::Option<::prost_types::Duration>, } /// Describes additional debugging info. #[derive(Clone, PartialEq, ::prost::Message)] pub struct DebugInfo { /// The stack trace entries indicating where the error occurred. - #[prost(string, repeated, tag="1")] + #[prost(string, repeated, tag = "1")] pub stack_entries: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, /// Additional debugging information provided by the server. - #[prost(string, tag="2")] + #[prost(string, tag = "2")] pub detail: ::prost::alloc::string::String, } /// Describes how a quota check failed. @@ -63,7 +63,7 @@ pub struct DebugInfo { #[derive(Clone, PartialEq, ::prost::Message)] pub struct QuotaFailure { /// Describes all quota violations. - #[prost(message, repeated, tag="1")] + #[prost(message, repeated, tag = "1")] pub violations: ::prost::alloc::vec::Vec, } /// Nested message and enum types in `QuotaFailure`. @@ -75,7 +75,7 @@ pub mod quota_failure { /// The subject on which the quota check failed. /// For example, "clientip:" or "project:". - #[prost(string, tag="1")] + #[prost(string, tag = "1")] pub subject: ::prost::alloc::string::String, /// A description of how the quota check failed. Clients can use this /// description to find more about the quota configuration in the service's @@ -84,7 +84,7 @@ pub mod quota_failure { /// /// For example: "Service disabled" or "Daily Limit for read operations /// exceeded". - #[prost(string, tag="2")] + #[prost(string, tag = "2")] pub description: ::prost::alloc::string::String, } } @@ -122,7 +122,7 @@ pub struct ErrorInfo { /// proximate cause of the error. Error reasons are unique within a particular /// domain of errors. This should be at most 63 characters and match /// /\\[A-Z0-9\_\\]+/. - #[prost(string, tag="1")] + #[prost(string, tag = "1")] pub reason: ::prost::alloc::string::String, /// The logical grouping to which the "reason" belongs. The error domain /// is typically the registered service name of the tool or product that @@ -130,7 +130,7 @@ pub struct ErrorInfo { /// generated by some common infrastructure, the error domain must be a /// globally unique value that identifies the infrastructure. For Google API /// infrastructure, the error domain is "googleapis.com". - #[prost(string, tag="2")] + #[prost(string, tag = "2")] pub domain: ::prost::alloc::string::String, /// Additional structured details about this error. /// @@ -140,8 +140,11 @@ pub struct ErrorInfo { /// {"instanceLimit": "100/request"}, should be returned as, /// {"instanceLimitPerRequest": "100"}, if the client exceeds the number of /// instances that can be created in a single (batch) request. - #[prost(map="string, string", tag="3")] - pub metadata: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, + #[prost(map = "string, string", tag = "3")] + pub metadata: ::std::collections::HashMap< + ::prost::alloc::string::String, + ::prost::alloc::string::String, + >, } /// Describes what preconditions have failed. /// @@ -151,7 +154,7 @@ pub struct ErrorInfo { #[derive(Clone, PartialEq, ::prost::Message)] pub struct PreconditionFailure { /// Describes all precondition violations. - #[prost(message, repeated, tag="1")] + #[prost(message, repeated, tag = "1")] pub violations: ::prost::alloc::vec::Vec, } /// Nested message and enum types in `PreconditionFailure`. @@ -162,18 +165,18 @@ pub mod precondition_failure { /// The type of PreconditionFailure. We recommend using a service-specific /// enum type to define the supported precondition violation subjects. For /// example, "TOS" for "Terms of Service violation". - #[prost(string, tag="1")] + #[prost(string, tag = "1")] pub r#type: ::prost::alloc::string::String, /// The subject, relative to the type, that failed. /// For example, "google.com/cloud" relative to the "TOS" type would indicate /// which terms of service is being referenced. - #[prost(string, tag="2")] + #[prost(string, tag = "2")] pub subject: ::prost::alloc::string::String, /// A description of how the precondition failed. Developers can use this /// description to understand how to fix the failure. /// /// For example: "Terms of service not accepted". - #[prost(string, tag="3")] + #[prost(string, tag = "3")] pub description: ::prost::alloc::string::String, } } @@ -182,7 +185,7 @@ pub mod precondition_failure { #[derive(Clone, PartialEq, ::prost::Message)] pub struct BadRequest { /// Describes all violations in a client request. - #[prost(message, repeated, tag="1")] + #[prost(message, repeated, tag = "1")] pub field_violations: ::prost::alloc::vec::Vec, } /// Nested message and enum types in `BadRequest`. @@ -193,10 +196,10 @@ pub mod bad_request { /// A path leading to a field in the request body. The value will be a /// sequence of dot-separated identifiers that identify a protocol buffer /// field. E.g., "field_violations.field" would identify this field. - #[prost(string, tag="1")] + #[prost(string, tag = "1")] pub field: ::prost::alloc::string::String, /// A description of why the request element is bad. - #[prost(string, tag="2")] + #[prost(string, tag = "2")] pub description: ::prost::alloc::string::String, } } @@ -206,11 +209,11 @@ pub mod bad_request { pub struct RequestInfo { /// An opaque string that should only be interpreted by the service generating /// it. For example, it can be used to identify requests in the service's logs. - #[prost(string, tag="1")] + #[prost(string, tag = "1")] pub request_id: ::prost::alloc::string::String, /// Any data that was used to serve this request. For example, an encrypted /// stack trace that can be sent back to the service provider for debugging. - #[prost(string, tag="2")] + #[prost(string, tag = "2")] pub serving_data: ::prost::alloc::string::String, } /// Describes the resource that is being accessed. @@ -219,22 +222,22 @@ pub struct ResourceInfo { /// A name for the type of resource being accessed, e.g. "sql table", /// "cloud storage bucket", "file", "Google calendar"; or the type URL /// of the resource: e.g. "type.googleapis.com/google.pubsub.v1.Topic". - #[prost(string, tag="1")] + #[prost(string, tag = "1")] pub resource_type: ::prost::alloc::string::String, /// The name of the resource being accessed. For example, a shared calendar /// name: "example.com_4fghdhgsrgh@group.calendar.google.com", if the current /// error is \\[google.rpc.Code.PERMISSION_DENIED\]\[google.rpc.Code.PERMISSION_DENIED\\]. - #[prost(string, tag="2")] + #[prost(string, tag = "2")] pub resource_name: ::prost::alloc::string::String, /// The owner of the resource (optional). /// For example, "user:" or "project:". - #[prost(string, tag="3")] + #[prost(string, tag = "3")] pub owner: ::prost::alloc::string::String, /// Describes what error is encountered when accessing this resource. /// For example, updating a cloud project may require the `writer` permission /// on the developer console project. - #[prost(string, tag="4")] + #[prost(string, tag = "4")] pub description: ::prost::alloc::string::String, } /// Provides links to documentation or for performing an out of band action. @@ -245,7 +248,7 @@ pub struct ResourceInfo { #[derive(Clone, PartialEq, ::prost::Message)] pub struct Help { /// URL(s) pointing to additional information on handling the current error. - #[prost(message, repeated, tag="1")] + #[prost(message, repeated, tag = "1")] pub links: ::prost::alloc::vec::Vec, } /// Nested message and enum types in `Help`. @@ -254,10 +257,10 @@ pub mod help { #[derive(Clone, PartialEq, ::prost::Message)] pub struct Link { /// Describes what the link offers. - #[prost(string, tag="1")] + #[prost(string, tag = "1")] pub description: ::prost::alloc::string::String, /// The URL of the link. - #[prost(string, tag="2")] + #[prost(string, tag = "2")] pub url: ::prost::alloc::string::String, } } @@ -268,9 +271,9 @@ pub struct LocalizedMessage { /// The locale used following the specification defined at /// /// Examples are: "en-US", "fr-CH", "es-MX" - #[prost(string, tag="1")] + #[prost(string, tag = "1")] pub locale: ::prost::alloc::string::String, /// The localized error message in the above locale. - #[prost(string, tag="2")] + #[prost(string, tag = "2")] pub message: ::prost::alloc::string::String, }