//
// Copyright (C) 2024 The Android Open-Source Project
//
// 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
//
//   http://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 = "proto2";
package android.release_config_proto;
option go_package = "android/soong/release_config/release_config_proto";

import "build_flags_common.proto";

// This protobuf file defines messages used to represent the build flags used by
// a release in a more human-editable form.  It is used for on-disk files in the
// source tree.
//
// The following format requirements apply across various message fields:
//
// # name: name of the flag
//
//    format: an uppercase string in SNAKE_CASE format starting with RELEASE_,
//      no consecutive underscores, and no leading digit. For example
//      RELEASE_MY_PACKAGE_FLAG is a valid name, while MY_PACKAGE_FLAG, and
//      RELEASE_MY_PACKAGE__FLAG are invalid.
//
// # namespace: namespace the flag belongs to
//
//    format: a lowercase string in snake_case format, no consecutive underscores, and no leading
//      digit. For example android_bar_system
//
// # package: package to which the flag belongs
//
//    format: lowercase strings in snake_case format, delimited by dots, no
//      consecutive underscores and no leading digit in each string. For example
//      com.android.mypackage is a valid name while com.android.myPackage,
//      com.android.1mypackage are invalid

message Value {
  oneof val {
    bool unspecified_value = 200;
    string string_value = 201;
    bool bool_value = 202;
    // If true, the flag is obsolete.  Assigning it further will be flagged.
    bool obsolete = 203;
  }
}

// The proto used in the source tree.
message FlagDeclaration {
  // The name of the flag.
  // See # name for format detail
  optional string name = 1;

  // Namespace the flag belongs to (required)
  // See # namespace for format detail
  optional string namespace = 2;

  // Text description of the flag's purpose.
  optional string description = 3;

  // The bug number associated with the flag.
  repeated string bugs = 4;

  // Value for the flag
  optional Value value = 201;

  // Workflow for this flag.
  optional Workflow workflow = 205;

  // The container for this flag.  This overrides any default container given
  // in the release_config_map message.
  repeated string containers = 206;

  // The package associated with this flag.
  // (when Gantry is ready for it) optional string package = 207;
  reserved 207;
}

message FlagValue {
  // Name of the flag.
  // See # name for format detail
  optional string name = 2;

  // Value for the flag
  optional Value value = 201;

  // If true, the flag is completely removed from the release config as if
  // never declared.
  optional bool redacted = 202;
}

enum ReleaseConfigType {
  // This is treated as `RELEASE_CONFIG`.
  CONFIG_TYPE_UNSPECIFIED = 0;

  // This is a normal release config.  This is the only ReleaseConfigType with
  // implicit inheritance.
  RELEASE_CONFIG = 1;

  // Same as RELEASE_CONFIG, except no implicit inheritance happens.
  // This is the "root" release config.
  EXPLICIT_INHERITANCE_CONFIG = 2;

  // This is a release config applied based on the TARGET_BUILD_VARIANT
  // environment variable, if the build flag RELEASE_BUILD_USE_VARIANT_FLAGS is
  // enabled.
  BUILD_VARIANT = 3;
}

// This replaces $(call declare-release-config).
message ReleaseConfig {
  // The name of the release config.
  // See # name for format detail
  optional string name = 1;

  // From which other release configs does this one inherit?
  repeated string inherits = 2;

  // List of names of the aconfig_value_set soong module(s) for this
  // contribution.
  repeated string aconfig_value_sets = 3;

  // Only aconfig flags are allowed in this release config.
  optional bool aconfig_flags_only = 4;

  // Prior stage(s) for flag advancement (during development).
  // Once a flag has met criteria in a prior stage, it can advance to this one.
  repeated string prior_stages = 5;

  // The ReleaseConfigType of this release config.
  optional ReleaseConfigType release_config_type = 6;

  // Whether to disallow this release config as TARGET_RELEASE.
  // If true, this release config can only be inherited, it cannot be used
  // directly in a build.
  optional bool disallow_lunch_use = 7;
}

// Any aliases.  These are used for continuous integration builder config.
message ReleaseAlias {
  // The name of the alias.
  optional string name = 1;

  // The release that `name` is an alias for.
  optional string target = 2;
}

// This provides the data from release_config_map.mk
message ReleaseConfigMap {
  // Any aliases.
  repeated ReleaseAlias aliases = 1;

  // Description of this map and its intended use.
  optional string description = 2;

  // The default container for flags declared here.
  repeated string default_containers = 3;

  // If needed, we can add these fields instead of hardcoding the location.
  // Flag declarations: `flag_declarations/*.textproto`
  // Release config contributions: `release_configs/*.textproto`
  // Flag values: `flag_values/{RELEASE_NAME}/*.textproto`
}
