/*
 * Copyright 2010-2015 JetBrains s.r.o.
 *
 * 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.
 */

package org.jetbrains.kotlin.metadata.jvm;

import "core/metadata/src/ext_options.proto";
import "core/metadata/src/metadata.proto";

option java_outer_classname = "JvmProtoBuf";
option optimize_for = LITE_RUNTIME;

message StringTableTypes {
  message Record {
    // The number of times this record should be repeated; this is used to collapse identical subsequent records in the list
    optional int32 range = 1 [default = 1];

    // Index of the predefined constant. If this field is present, the associated string is ignored
    optional int32 predefined_index = 2;

    // A string which should be used. If this field is present, both the associated string and the predefined string index are ignored
    optional string string = 6;

    enum Operation {
      NONE = 0;

      // replaceAll('$', '.')
      // java/util/Map$Entry -> java/util/Map.Entry;
      INTERNAL_TO_CLASS_ID = 1;

      // substring(1, length - 1) and then replaceAll('$', '.')
      // Ljava/util/Map$Entry; -> java/util/Map.Entry
      DESC_TO_CLASS_ID = 2;
    }

    // Perform a described operation on the string
    optional Operation operation = 3 [default = NONE];

    // If this field is present, the "substring" operation must be performed with the first element of this list as the start index,
    // and the second element as the end index.
    // If an operation is not NONE, it's applied _after_ this substring operation
    repeated int32 substring_index = 4 [packed = true];

    // If this field is present, the "replaceAll" operation must be performed with the first element of this list as the code point
    // of the character to replace, and the second element as the code point of the replacement character
    repeated int32 replace_char = 5 [packed = true];
  }

  repeated Record record = 1;

  // Indices of strings which are names of local classes or anonymous objects
  repeated int32 local_name = 5 [packed = true];
}

message JvmMethodSignature {
  optional int32 name = 1 [(string_id_in_table) = true];

  // JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
  optional int32 desc = 2 [(string_id_in_table) = true];
}

message JvmFieldSignature {
  optional int32 name = 1 [(string_id_in_table) = true];

  // JVM descriptor of the field type, e.g. 'Ljava/lang/String;'
  optional int32 desc = 2 [(string_id_in_table) = true];
}

message JvmPropertySignature {
  optional JvmFieldSignature field = 1;

  // Annotations on properties are written on a synthetic method with this signature
  optional JvmMethodSignature synthetic_method = 2;

  optional JvmMethodSignature getter = 3;
  optional JvmMethodSignature setter = 4;

  // The delegate field of delegated properties may be optimized out; `getDelegate` should
  // then call this method instead
  optional JvmMethodSignature delegate_method = 5;
}

extend Constructor {
  optional JvmMethodSignature constructor_signature = 100;
}

extend Function {
  optional JvmMethodSignature method_signature = 100;

  // For lambdas from bodies of inline functions copied to the use site, the JVM internal name of the original
  // lambda class this class is copied from
  optional int32 lambda_class_origin_name = 101 [(string_id_in_table) = true];
}

extend Property {
  optional JvmPropertySignature property_signature = 100;

  /**
    isMovedFromInterfaceCompanion   true if this property is declared in an interface companion, and the field is stored in the interface
   */
  optional int32 flags = 101 [default = 0];
}

extend Type {
  repeated Annotation type_annotation = 100;
  optional bool is_raw = 101;
}

extend TypeParameter {
  repeated Annotation type_parameter_annotation = 100;
}

extend Class {
  // If absent, assumed to be "main" (JvmProtoBufUtil.DEFAULT_MODULE_NAME)
  optional int32 class_module_name = 101 [(string_id_in_table) = true];

  repeated Property class_local_variable = 102;

  // For anonymous objects from bodies of inline functions copied to the use site, the JVM internal name of the original
  // anonymous object this class is copied from
  optional int32 anonymous_object_origin_name = 103 [(string_id_in_table) = true];


  // first bit: isFunctionBodyInInterface: 0 if actual body generated in DefaultImpl, 1 - otherwise (in interface default method)
  // second bit: is all-compatibility mode or not, 1 - yes, 0 - no
  optional int32 jvm_class_flags = 104 [default = 0];
}

extend Package {
  optional int32 package_module_name = 101 [(string_id_in_table) = true];

  repeated Property package_local_variable = 102;
}
