# Copyright (C) 2020-present MongoDB, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the Server Side Public License, version 1,
# as published by MongoDB, Inc.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# Server Side Public License for more details.
#
# You should have received a copy of the Server Side Public License
# along with this program. If not, see
# <http://www.mongodb.com/licensing/server-side-public-license>.
#
# As a special exception, the copyright holders give permission to link the
# code of portions of this program with the OpenSSL library under certain
# conditions as described in each individual source file and distribute
# linked combinations including the program with the OpenSSL library. You
# must comply with the Server Side Public License in all respects for
# all of the code used other than as permitted herein. If you modify file(s)
# with this exception, you may extend this exception to your version of the
# file(s), but you are not obligated to do so. If you do not wish to do so,
# delete this exception statement from your version. If you delete this
# exception statement from all source files in the program, then also delete
# it in the license file.
#
global:
    cpp_namespace: "mongo"
    cpp_includes:
        - "mongo/db/basic_types.h"
        - "mongo/idl/generic_argument.h"
        - "mongo/s/shard_version.h"

imports:
    - "mongo/client/read_preference_setting.idl"
    - "mongo/db/basic_types.idl"
    - "mongo/db/repl/read_concern.idl"
    - "mongo/db/repl/read_concern_args.idl"
    - "mongo/db/repl/replication_types.idl"
    - "mongo/db/session/logical_session_id.idl"
    - "mongo/db/vector_clock.idl"
    - "mongo/db/write_concern_options.idl"       
    - "mongo/rpc/metadata/impersonated_user_metadata.idl"
    - "mongo/s/sharding_types.idl"
    - "mongo/s/gossiped_routing_cache.idl"

structs:
    GenericArguments:
        description: "Arguments accepted by all commands."
        strict: false
        is_generic_cmd_list: "arg" 
        # Note that the _types_ of these fields are not checked for API version compatability! 
        # Historically, these types were parsed and serialized directly from BSON by hand-written  
        # C++ code. The API comapatibility checker does not enforce stability of the types of these fields,
        # only of their names (i.e. that none are removed or have their name changed). 
        fields:
            apiVersion:
                type: string
                forward_to_shards: false
                optional: true
                stability: "stable"
            apiStrict:
                type: bool
                forward_to_shards: false
                optional: true
                stability: "stable"
            apiDeprecationErrors:
                type: bool
                forward_to_shards: false
                optional: true
                stability: "stable"
            # The IDL compiler injects this directly into command requests, so we ignore it here.
            # $db:
            #     type: database_name
            #     cpp_name: "dbName"
            #     forward_to_shards: false
            #     ignore: true
            #     stability: "stable"
            maxTimeMS:
                type: exactInt64
                validator: { gte: 0, lte: 2147483647 } # [0, 2^31 - 1]
                forward_to_shards: true
                optional: true
                stability: "stable"
            readConcern:
                type: ReadConcern
                forward_to_shards: true
                optional: true
                stability: "stable"
            writeConcern:
                type: WriteConcern
                forward_to_shards: true
                optional: true            
                stability: "stable"
            lsid:
                type: LogicalSessionFromClient
                forward_to_shards: true
                optional: true
                stability: "stable"
            clientOperationKey:
                type: uuid
                forward_to_shards: true
                optional: true                
                stability: "stable"
            txnNumber:
                type: TxnNumber
                forward_to_shards: true
                optional: true            
                stability: "stable"
            autocommit:
                type: bool
                forward_to_shards: true
                optional: true
                stability: "stable"
            startTransaction:
                type: bool
                forward_to_shards: true
                optional: true
                stability: "stable"
            stmtId:
                type: StmtId
                forward_to_shards: true
                # Various write commands treat this argument differently, so we ignore it at the generic argument
                # level and instead defer to the individual commands' definitions of it. They should all use the same
                # serialization rules, though.
                #
                # Note that if a command does not include a stmtId field in its definition, the re-serialized BSON
                # of a parsed instance of that command struct will not contain stmtId, even if the original request
                # did.
                ignore: true
                stability: "stable"
            comment:
                type: IDLAnyTypeOwned
                forward_to_shards: true
                optional: true
                stability: "stable"
            $readPreference:
                type: readPreference
                cpp_name: "readPreference"
                forward_to_shards: false
                optional: true
                stability: "stable"
            $clusterTime:
                type: ClusterTime
                cpp_name: "dollarClusterTime"
                forward_to_shards: false
                optional: true
                stability: "stable"
            $audit:
                type: ImpersonatedUserMetadata
                cpp_name: "dollarAudit"
                forward_to_shards: false
                optional: true
                stability: "internal"
            $client:
                type: object_owned
                cpp_name: "dollarClient"
                forward_to_shards: false
                optional: true
                stability: "internal"
            $configServerState:
                type: object_owned
                cpp_name: "dollarConfigServerState"
                forward_to_shards: false
                optional: true
                stability: "internal"
            allowImplicitCollectionCreation:
                type: bool
                forward_to_shards: false
                optional: true
                stability: "internal"
            $oplogQueryData:
                type: IDLAnyTypeOwned
                cpp_name: "dollarOplogQueryData"
                forward_to_shards: false
                optional: true
                stability: "internal"
            $queryOptions:
                type: object_owned
                cpp_name: unwrappedReadPref
                forward_to_shards: true
                optional: true
                stability: "internal"
            $replData:
                type: IDLAnyTypeOwned
                cpp_name: "dollarReplData"
                forward_to_shards: false
                optional: true
                stability: "internal"
            databaseVersion:
                type: database_version
                forward_to_shards: false
                optional: true
                stability: "internal"
            help:
                type: bool
                forward_to_shards: false
                optional: true
                stability: "internal"
            shardVersion:
                type: shard_version
                forward_to_shards: false
                optional: true
                stability: "internal"
            tracking_info:
                type: object_owned
                forward_to_shards: false
                optional: true
                stability: "internal"
            coordinator:
                type: bool
                forward_to_shards: true
                optional: true
                stability: "internal"
            maxTimeMSOpOnly:
                type: exactInt64
                validator: { callback: "::mongo::validateMaxTimeMSOpOnly" }
                forward_to_shards: false
                optional: true
                stability: "internal"
            usesDefaultMaxTimeMS:
                type: bool
                forward_to_shards: false
                optional: true
                stability: "internal"
            $configTime:
                type: timestamp
                cpp_name: "dollarConfigTime"
                forward_to_shards: false
                optional: true
                stability: "internal"
            $topologyTime:
                type: timestamp
                cpp_name: "dollarTopologyTime"
                forward_to_shards: false
                optional: true
                stability: "internal"
            txnRetryCounter:
                type: TxnRetryCounter
                forward_to_shards: true
                optional: true
                stability: "internal"
            mayBypassWriteBlocking:
                type: bool
                forward_to_shards: false
                optional: true
                stability: "internal"
            expectPrefix:
                type: bool
                forward_to_shards: false
                optional: true
                stability: "internal"
            requestGossipRoutingCache:
                type: array<IDLAnyTypeOwned>
                forward_to_shards: false
                optional: true
                stability: "internal"
            startOrContinueTransaction:
                type: bool
                forward_to_shards: true
                optional: true
                stability: "internal"

    GenericReplyFields:
        description: "Fields that may appear in any command reply."
        strict: false
        is_generic_cmd_list: "reply"
        # The unstable fields here are marked as "internal" rather than actually "unstable" because otherwise the
        # server internally parsing a command reply that contained one of the unstable fields along with
        # apiStrict: true would fail at no fault to the user. apiStrict doesn't really make sense to use with reply
        # parsing, but it's very difficult to audit the codebase to ensure it isn't being used for that. That said,
        # the drawback here is mostly just aesthetic--as far as the API compatibility checker is concerned, "internal"
        # and "unstable" are both considered unstable, so we don't lose any functionality here or risk breaking any stable
        # fields.
        fields:
            $clusterTime:
                type: ClusterTime
                cpp_name: "dollarClusterTime"
                forward_from_shards: false
                optional: true
                stability: "stable"
            operationTime:
                type: logicalTime
                forward_from_shards: false
                optional: true
                stability: "stable"
            $configServerState:
                type: object_owned
                cpp_name: "dollarConfigServerState"
                forward_from_shards: false
                optional: true
                stability: "internal"
            $gleStats:
                type: object_owned
                cpp_name: "dollarGleStats"
                forward_from_shards: false
                optional: true
                stability: "internal"
            lastCommittedOpTime:
                type: optime
                forward_from_shards: false
                optional: true
                stability: "internal"
            readOnly:
                type: bool
                forward_from_shards: false
                optional: true
                stability: "internal"
            additionalParticipants:
                type: array<object_owned> 
                forward_from_shards: false
                optional: true
                stability: "internal"
            $configTime:
                type: timestamp
                cpp_name: "dollarConfigTime"
                forward_from_shards: false
                optional: true
                stability: "internal"
            $replData:
                type: object_owned
                cpp_name: "dollarReplData"
                forward_from_shards: false
                optional: true
                stability: "internal"
            $topologyTime:
                type: timestamp
                cpp_name: "dollarTopologyTime"
                forward_from_shards: false
                optional: true
                stability: "internal"
            $oplogQueryData:
                type: object_owned
                cpp_name: "dollarOplogQueryData"
                forward_from_shards: false
                optional: true
                stability: "internal"
            ok:
                type: safeBool
                forward_from_shards: true
                optional: true
                stability: "internal"
            routingCacheGossip:
                type: array<GossipedRoutingCache>
                forward_from_shards: false
                optional: true
                stability: "internal"

