// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.cloud.cpp.generator;

message ServiceConfiguration {
  string service_proto_path = 1;
  string product_path = 2;
  string initial_copyright_year = 3;

  // Omit the generation of the (sync) APIs for these RPCs. Include any
  // deprecated RPCs here that we don't need for backwards compatibility.
  repeated string omitted_rpcs = 4;

  string service_endpoint_env_var = 5;
  string emulator_endpoint_env_var = 6;

  // Generating async APIs is typically unnecessary for RPCs that are
  // non-streaming, non-paginated, and not longrunning operations. If we need
  // to generate an async API for such an RPC, we can list it here.
  //
  // Only the async API will be generated for RPCs listed both here and in
  // `omitted_rpcs`.
  repeated string gen_async_rpcs = 7;

  repeated string omitted_services = 8;

  // If set to true generate the `gcpxxV1` alias for our inline namespace. Older
  // versions of the generated libraries need this, but new libraries should not
  // have it.
  bool backwards_compatibility_namespace_alias = 9;

  // If all rpcs in the service have the same set of retryable status codes,
  // typically found in the service_config.json accompanying the proto files,
  // generate the ServiceNameRetryTraits struct using the provided codes.
  // These codes can be service name qualified for files that define more than
  // one service. Unqualified codes are added to each service in the file.
  // If no codes are listed, do not attempt to generate the retry traits.
  repeated string retryable_status_codes = 10;

  // If set, the `*Client` class is not generated. This is useful in services
  // where the public API needs a hand-crafted wrapper, for example, because
  // the retry/resume policy is more complex, or because the proto-level API
  // does not provide good application-level concepts (consider chunking for
  // rows or values).
  bool omit_client = 11;

  // If set, the `*Connection` class and its helpers are not generated. This
  // is useful in services where the `*Connection` requires very custom code,
  // for example:
  // * Storage already had a hand-crafted analog to the `*Connection` class.
  // * Pub/Sub Lite, where we think the generated `*Stub` classes are useful,
  //   but the `*Connection` requires custom algorithms.
  // * Anything that requires a custom resume algorithm for streaming RPCs.
  //
  // In most cases one would want to set `omit_client` to true if this flag
  // is also set.
  bool omit_connection = 13;

  // If additional proto files are needed that aren't imported by the service
  // file, add them using this field. This typically happens when an annotation
  // lists a type that is not defined in any of the imported proto files.
  repeated string additional_proto_files = 12;

  // If set, the factory function for the `*Stub` class and its decorators is
  // not generated. This is useful if the library requires a custom set of
  // decorators, for example, Storage requires a round-robin decorator to get
  // good performance.
  bool omit_stub_factory = 14;

  // Control the overloads generated for `Make*Connection()`.
  enum EndpointLocationStyle {
    // Default. `Make*Connection(Options options = {})`.
    LOCATION_INDEPENDENT = 0;

    // `Make*Connection(std::string const& location, Options options = {})`.
    LOCATION_DEPENDENT = 1;

    // Both of the above, for services that were initially released as
    // "LOCATION_INDEPENDENT" (probably with a useless default endpoint),
    // but were subsequently acknowledged to be "LOCATION_DEPENDENT".
    // Do not use for new services.
    LOCATION_DEPENDENT_COMPAT = 2;
  }
  EndpointLocationStyle endpoint_location_style = 15;

  // Control whether round-robin decorator is generated.
  bool generate_round_robin_decorator = 16;

  // While most services default to gRPC, a handful are REST only. Additionally,
  // most gRPC services can also support REST via gRPC/HTTP transcoding
  // https://cloud.google.com/endpoints/docs/grpc/transcoding.
  bool generate_rest_transport = 17;

  // Sometimes we want to add a non-GA client to an already-GA library, (e.g. if
  // the service itself is in Private Preview).
  //
  // If set, this flag will add an `ExperimentalTag` parameter to the client
  // constructor and the connection factory function.
  bool experimental = 18;

  // We use this setting to maintain backwards compatibility when relocating a
  // service from the undesired `forwarding_product_path` to the desired
  // `product_path`.
  //
  // If set, generate backwards compatibility headers at the
  // `forwarding_product_path`. These headers define aliases (in the namespace
  // derived from `forwarding_product_path`), which point to types defined at
  // the `product_path` (in the namespace derived from `product_path`).
  //
  // For details on why we would relocate a service, see #10170, or
  // https://github.com/googleapis/google-cloud-cpp/blob/main/doc/adr/2022-11-11-multiple-versions-of-GCP-service-in-one-library.md
  string forwarding_product_path = 19;

  // Force the generation of the (sync) APIs for these deprecated RPCs so
  // as to maintain backwards compatibility with previous releases.
  repeated string emitted_rpcs = 20;

  // Override idempotency policy values for specific rpcs.
  message IdempotencyOverride {
    // rpc_name should be qualified with the service name e.g.: Service.Method.
    string rpc_name = 1;
    enum Idempotency {
      IDEMPOTENT = 0;
      NON_IDEMPOTENT = 1;
    }
    Idempotency idempotency = 2;
  }
  repeated IdempotencyOverride idempotency_overrides = 21;

  // This need not be explicitly set to true as the generator will check if the
  // field has been set, and assign a value of true if not set.
  optional bool generate_grpc_transport = 22;

  // If set to `true` the generator will *NOT* create a .repo-metadata.json
  // file. This is useful when multiple services target the same directory.
  bool omit_repo_metadata = 23;

  enum ProtoFileSource {
    GOOGLEAPIS = 0;
    DISCOVERY_DOCUMENT = 1;
  }
  ProtoFileSource proto_file_source = 24;

  // Some REST services expect JSON fields names in snake_case, while most other
  // REST services expect JSON in camelCase. When true this flag instructs the
  // generator to emit field names as they are defined in the proto files,
  // which by style convention is typically snake_case. When false, the field
  // names will be converted to camelCase.
  bool preserve_proto_field_names_in_json = 25;

  // A mapping from the service name as defined in the googleapis repo to the
  // name that will be used for the library generation.
  map<string, string> service_name_mapping = 26;

  // A mapping from the service name as defined in the googleapis repo or
  // overridden by an entry in service_name_mapping to a comment for the
  // service. This will replace the service comment from the upstream repo.
  map<string, string> service_name_to_comment = 27;
}

message DiscoveryDocumentDefinedProduct {
  // Location of Discovery Document for services that only support REST.
  string discovery_document_url = 1;

  // Products that do not use google::longrunning::Operation to handle long
  // running operations typically define their own operation type and services
  // to handle them. We need to take care to generate these as simple,
  // synchronous services.
  repeated string operation_services = 3;

  // Services that are generated from the protos created from the
  // discovery document.
  repeated ServiceConfiguration rest_services = 2;
}

message GeneratorConfiguration {
  // Services that have proto definitions in googleapis/googleapis.
  repeated ServiceConfiguration service = 1;

  // Services that are only defined via Discovery Document.
  repeated DiscoveryDocumentDefinedProduct discovery_products = 2;
}
