/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

// Fory Options for FDL (Fory Definition Language)
// @author: chaokunyang
//
// This file defines custom options that can be used in FDL schemas
// to control Fory serialization behavior. Copy this file into your
// project to use these options.
//
// Usage Examples:
//
// File-level options:
//   option (fory).use_record_for_java_message = true;
//   option (fory).enable_auto_type_id = true;
//   option (fory).go_nested_type_style = "camelcase";
//   option (fory).swift_namespace_style = "flatten";
//
// Message options:
//   message MyMessage {
//     option (fory).id = 100;
//     option (fory).evolving = false;
//     option (fory).use_record_for_java = true;
//   }
//
// Enum options:
//   enum Status {
//     option (fory).id = 101;
//   }
//
// Field options:
//   message Example {
//     MyType field = 1 [(fory).ref = true, (fory).nullable = true];
//   }

syntax = "proto3";

package fory;

import "google/protobuf/descriptor.proto";

// ===========================================================================
// File-Level Options
// ===========================================================================
// These options apply to the entire FDL file and affect all generated code.

message ForyFileOptions {
  // Generate Java records instead of classes for all messages in this file.
  // Only applies to Java code generation.
  // Default: false (generates traditional POJOs)
  optional bool use_record_for_java_message = 1;

  // Enable polymorphism support for all types in this file.
  // When true, type metadata is included in serialization for polymorphic
  // dispatch. Default: false
  optional bool polymorphism = 2;

  // Control auto-generation of type IDs when none are specified.
  // When true (default in the compiler), IDs are generated from the package
  // namespace and type name. When false, types without explicit IDs are
  // registered by namespace and name.
  optional bool enable_auto_type_id = 3;

  // Enable schema evolution for all messages in this file by default.
  // When false, messages default to STRUCT/NAMED_STRUCT unless overridden.
  // Default: true.
  optional bool evolving = 4;

  // Go nested type naming style.
  // - "underscore" (default): Parent_Child
  // - "camelcase": ParentChild
  // Equivalent to compiler flag: --go_nested_type_style
  optional string go_nested_type_style = 5;

  // Swift package namespace style.
  // - "enum" (default): nested enum namespace wrappers
  // - "flatten": package-derived prefix on top-level type names
  // Equivalent to compiler flag: --swift_namespace_style
  //
  // Note: namespace wrapper/prefixing is only applied when package/namespace is non-empty.
  optional string swift_namespace_style = 6;
}

extend google.protobuf.FileOptions { optional ForyFileOptions fory = 50001; }

// ===========================================================================
// Message-Level Options
// ===========================================================================
// These options apply to individual message definitions.

message ForyMessageOptions {
  // Unique type ID for cross-language registration.
  // Used for efficient type lookup during deserialization.
  // Must be a positive integer unique within the schema.
  // If not specified, namespace-based registration is used.
  optional int32 id = 1;

  // Enable schema evolution for this message.
  // When true (default), fields can be added/removed with forward/backward
  // compatibility. When false, schema is fixed like a struct - no changes
  // allowed, better performance.
  optional bool evolving = 2;

  // Generate a Java record instead of a class for this specific message.
  // Overrides file-level use_record_for_java_message setting.
  // Only applies to Java code generation.
  optional bool use_record_for_java = 3;

  // Mark this message as deprecated.
  // Generates appropriate deprecation annotations in target languages.
  optional bool deprecated = 4;

  // Custom namespace for type registration.
  // Overrides the default package-based namespace.
  optional string namespace = 5;
}

extend google.protobuf.MessageOptions {
  optional ForyMessageOptions fory = 50001;
}

// ===========================================================================
// Enum-Level Options
// ===========================================================================
// These options apply to individual enum definitions.

message ForyEnumOptions {
  // Unique type ID for cross-language registration.
  // Used for efficient type lookup during deserialization.
  // Must be a positive integer unique within the schema.
  optional int32 id = 1;

  // Mark this enum as deprecated.
  optional bool deprecated = 2;
}

extend google.protobuf.EnumOptions { optional ForyEnumOptions fory = 50001; }

// ===========================================================================
// Field-Level Options
// ===========================================================================
// These options apply to individual field definitions.

message ForyFieldOptions {
  // Enable reference tracking for this field.
  // When true, Fory tracks object references to handle:
  // - Circular references (e.g., tree structures with parent pointers)
  // - Shared references (same object referenced multiple times)
  // Default: false
  optional bool ref = 1;

  // Mark this field as nullable.
  // When true, the field can be null/None/nil.
  // Default: false (field must have a value)
  optional bool nullable = 2;

  // Mark this field as deprecated.
  optional bool deprecated = 3;

  // Generate a weak reference for ref fields in C++/Rust codegen.
  // Requires ref=true or a ref modifier. Ignored by Java/Python/Go.
  // Default: false
  optional bool weak_ref = 4;
}

extend google.protobuf.FieldOptions { optional ForyFieldOptions fory = 50001; }
