import type { IMessageType } from "./message-type-contract";
import type { JsonValue } from "./json-typings";
/**
 * Describes a protobuf enum for runtime reflection.
 *
 * The tuple consists of:
 *
 *
 * [0] the protobuf type name
 *
 * The type name follows the same rules as message type names.
 * See `MessageInfo` for details.
 *
 *
 * [1] the enum object generated by Typescript
 *
 * We generate standard Typescript enums for protobuf enums. They are compiled
 * to lookup objects that map from numerical value to name strings and vice
 * versa and can also contain alias names.
 *
 * See https://www.typescriptlang.org/docs/handbook/enums.html#reverse-mappings
 *
 * We use this lookup feature to when encoding / decoding JSON format. The
 * enum is guaranteed to have a value for 0. We generate an entry for 0 if
 * none was declared in .proto because we would need to support custom default
 * values if we didn't.
 *
 *
 * [2] the prefix shared by all original enum values (optional)
 *
 * If all values of a protobuf enum share a prefix, it is dropped in the
 * generated enum. For example, the protobuf enum `enum My { MY_FOO, MY_BAR }`
 * becomes the typescript enum `enum My { FOO, BAR }`.
 *
 * Because the JSON format requires the original value name, we store the
 * dropped prefix here, so that the JSON format implementation can restore
 * the original value names.
 */
export declare type EnumInfo = readonly [
/**
 * The protobuf type name of the enum
 */
string, 
/**
 * The enum object generated by Typescript
 */
{
    [key: number]: string;
    [k: string]: number | string;
}, 
/**
 * The prefix shared by all original enum values
 */
string?];
/**
 * Describes a protobuf message for runtime reflection.
 */
export interface MessageInfo {
    /**
     * The protobuf type name of the message, including package and
     * parent types if present.
     *
     * If the .proto file included a `package` statement, the type name
     * starts with '.'.
     *
     * Examples:
     * 'MyNamespaceLessMessage'
     * '.my_package.MyMessage'
     * '.my_package.ParentMessage.ChildMessage'
     */
    readonly typeName: string;
    /**
     * Simple information for each message field, in the order
     * of declaration in the source .proto.
     */
    readonly fields: readonly FieldInfo[];
    /**
     * Contains custom message options from the .proto source in JSON format.
     */
    readonly options: {
        [extensionName: string]: JsonValue;
    };
}
/**
 * Version of `MessageInfo` that allows the following properties
 * to be omitted:
 * - "fields": omitting means the message has no fields
 * - "options": omitting means the message has no options
 */
export declare type PartialMessageInfo = PartialPartial<MessageInfo, "fields" | "options">;
declare type PartialPartial<T, K extends keyof T> = Partial<Pick<T, K>> & Omit<T, K>;
/**
 * Describes a field of a protobuf message for runtime
 * reflection. We distinguish between the following
 * kinds of fields:
 *
 * "scalar": string, bool, float, int32, etc.
 * See https://developers.google.com/protocol-buffers/docs/proto3#scalar
 *
 * "enum": field was declared with an enum type.
 *
 * "message": field was declared with a message type.
 *
 * "map": field was declared with map<K,V>.
 *
 *
 * Every field, regardless of it's kind, always has the following properties:
 *
 * "no": The field number of the .proto field.
 * "name": The original name of the .proto field.
 * "localName": The name of the field as used in generated code.
 * "jsonName": The name for JSON serialization / deserialization.
 * "options": Custom field options from the .proto source in JSON format.
 *
 *
 * Other properties:
 *
 * - Fields of kind "scalar", "enum" and "message" can have a "repeat" type.
 * - Fields of kind "scalar" and "enum" can have a "repeat" type.
 * - Fields of kind "scalar", "enum" and "message" can be member of a "oneof".
 *
 * A field can be only have one of the above properties set.
 *
 * Options for "scalar" fields:
 *
 * - 64 bit integral types can provide "L" - the JavaScript representation
 *   type.
 *
 */
export declare type FieldInfo = fiRules<fiScalar> | fiRules<fiEnum> | fiRules<fiMessage> | fiRules<fiMap>;
/**
 * Version of `FieldInfo` that allows the following properties
 * to be omitted:
 * - "localName", "jsonName": can be omitted if equal to lowerCamelCase(name)
 * - "opt": can be omitted if false
 * - "repeat", can be omitted if RepeatType.NO
 *
 * Use `normalizeFieldInfo()` to fill the omitted fields with
 * their standard values.
 */
export declare type PartialFieldInfo = fiPartialRules<fiScalar> | fiPartialRules<fiEnum> | fiPartialRules<fiMessage> | fiPartialRules<fiMap>;
interface fiShared {
    /**
     * The field number of the .proto field.
     */
    no: number;
    /**
     * The original name of the .proto field.
     */
    name: string;
    /**
     * The name of the field as used in generated code.
     */
    localName: string;
    /**
     * The name for JSON serialization / deserialization.
     */
    jsonName: string;
    /**
     * The name of the `oneof` group, if this field belongs to one.
     */
    oneof: string | undefined;
    /**
     * Contains custom field options from the .proto source in JSON format.
     */
    options?: {
        [extensionName: string]: JsonValue;
    };
}
interface fiScalar extends fiShared {
    kind: 'scalar';
    /**
     * Scalar type of the field.
     */
    T: ScalarType;
    /**
     * Representation of 64 bit integral types (int64, uint64, sint64,
     * fixed64, sfixed64).
     *
     * If this option is set for other scalar types, it is ignored.
     * Omitting this option is equivalent to `STRING`.
     */
    L?: LongType;
    /**
     * Is the field repeated?
     */
    repeat: RepeatType;
    /**
     * Is the field optional?
     */
    opt: boolean;
}
interface fiMessage extends fiShared {
    kind: 'message';
    /**
     * Message handler for the field.
     */
    T: () => IMessageType<any>;
    /**
     * Is the field repeated?
     */
    repeat: RepeatType;
}
interface fiEnum extends fiShared {
    kind: 'enum';
    /**
     * Enum type information for the field.
     */
    T: () => EnumInfo;
    /**
     * Is the field repeated?
     */
    repeat: RepeatType;
    /**
     * Is the field optional?
     */
    opt: boolean;
}
interface fiMap extends fiShared {
    kind: 'map';
    /**
     * Map key type.
     *
     * The key_type can be any integral or string type
     * (so, any scalar type except for floating point
     * types and bytes)
     */
    K: Exclude<ScalarType, ScalarType.FLOAT | ScalarType.DOUBLE | ScalarType.BYTES>;
    /**
     * Map value type. Can be a `ScalarType`, enum type information,
     * or type handler for a message.
     */
    V: {
        kind: 'scalar';
        T: ScalarType;
        L?: LongType;
    } | {
        kind: 'enum';
        T: () => EnumInfo;
    } | {
        kind: 'message';
        T: () => IMessageType<any>;
    };
}
declare type fiRules<T> = Omit<T, 'oneof' | 'repeat' | 'opt'> & ({
    repeat: RepeatType.NO;
    opt: false;
    oneof: undefined;
} | {
    repeat: RepeatType.NO;
    opt: true;
    oneof: undefined;
} | {
    repeat: RepeatType.PACKED | RepeatType.UNPACKED;
    opt: false;
    oneof: undefined;
} | {
    repeat: RepeatType.NO;
    opt: false;
    oneof: string;
});
declare type fiPartialRules<T> = Omit<T, 'jsonName' | 'localName' | 'oneof' | 'repeat' | 'opt'> & ({
    localName?: string;
    jsonName?: string;
    repeat?: RepeatType.NO;
    opt?: false;
    oneof?: undefined;
} | {
    localName?: string;
    jsonName?: string;
    repeat?: RepeatType.NO;
    opt: true;
    oneof?: undefined;
} | {
    localName?: string;
    jsonName?: string;
    repeat: RepeatType.PACKED | RepeatType.UNPACKED;
    opt?: false;
    oneof?: undefined;
} | {
    localName?: string;
    jsonName?: string;
    repeat?: RepeatType.NO;
    opt?: false;
    oneof: string;
});
/**
 * Scalar value types. This is a subset of field types declared by protobuf
 * enum google.protobuf.FieldDescriptorProto.Type The types GROUP and MESSAGE
 * are omitted, but the numerical values are identical.
 */
export declare enum ScalarType {
    DOUBLE = 1,
    FLOAT = 2,
    INT64 = 3,
    UINT64 = 4,
    INT32 = 5,
    FIXED64 = 6,
    FIXED32 = 7,
    BOOL = 8,
    STRING = 9,
    BYTES = 12,
    UINT32 = 13,
    SFIXED32 = 15,
    SFIXED64 = 16,
    SINT32 = 17,
    SINT64 = 18
}
/**
 * JavaScript representation of 64 bit integral types. Equivalent to the
 * field option "jstype".
 *
 * By default, protobuf-ts represents 64 bit types as `bigint`.
 *
 * You can change the default behaviour by enabling the plugin parameter
 * `long_type_string`, which will represent 64 bit types as `string`.
 *
 * Alternatively, you can change the behaviour for individual fields
 * with the field option "jstype":
 *
 * ```protobuf
 * uint64 my_field = 1 [jstype = JS_STRING];
 * uint64 other_field = 2 [jstype = JS_NUMBER];
 * ```
 */
export declare enum LongType {
    /**
     * Use JavaScript `bigint`.
     *
     * Field option `[jstype = JS_NORMAL]`.
     */
    BIGINT = 0,
    /**
     * Use JavaScript `string`.
     *
     * Field option `[jstype = JS_STRING]`.
     */
    STRING = 1,
    /**
     * Use JavaScript `number`.
     *
     * Large values will loose precision.
     *
     * Field option `[jstype = JS_NUMBER]`.
     */
    NUMBER = 2
}
/**
 * Protobuf 2.1.0 introduced packed repeated fields.
 * Setting the field option `[packed = true]` enables packing.
 *
 * In proto3, all repeated fields are packed by default.
 * Setting the field option `[packed = false]` disables packing.
 *
 * Packed repeated fields are encoded with a single tag,
 * then a length-delimiter, then the element values.
 *
 * Unpacked repeated fields are encoded with a tag and
 * value for each element.
 *
 * `bytes` and `string` cannot be packed.
 */
export declare enum RepeatType {
    /**
     * The field is not repeated.
     */
    NO = 0,
    /**
     * The field is repeated and should be packed.
     * Invalid for `bytes` and `string`, they cannot be packed.
     */
    PACKED = 1,
    /**
     * The field is repeated but should not be packed.
     * The only valid repeat type for repeated `bytes` and `string`.
     */
    UNPACKED = 2
}
/**
 * Turns PartialFieldInfo into FieldInfo.
 */
export declare function normalizeFieldInfo(field: PartialFieldInfo): FieldInfo;
/**
 * Read custom field options from a generated message type.
 *
 * @deprecated use readFieldOption()
 */
export declare function readFieldOptions<T extends object>(messageType: MessageInfo, fieldName: string | number, extensionName: string, extensionType: IMessageType<T>): T | undefined;
/**
 * Read a custom field option.
 *
 * ```proto
 * message MyMessage {
 *   int32 my_field = 1 [(acme.field_opt) = true];
 * }
 * ```
 *
 * ```typescript
 * let val = readFieldOption(MyMessage, 'myField', 'acme.field_opt')
 * ```
 */
export declare function readFieldOption<T extends object>(messageType: MessageInfo, fieldName: string | number, extensionName: string): JsonValue | undefined;
export declare function readFieldOption<T extends object>(messageType: MessageInfo, fieldName: string | number, extensionName: string, extensionType: IMessageType<T>): T | undefined;
/**
 * Read a custom message option.
 *
 * ```proto
 * message MyMessage {
 *   option acme.message_opt = true;
 * }
 * ```
 *
 * ```typescript
 * let val = readMessageOption(MyMessage, 'acme.message_opt')
 * ```
 */
export declare function readMessageOption<T extends object>(messageType: MessageInfo, extensionName: string): JsonValue | undefined;
export declare function readMessageOption<T extends object>(messageType: MessageInfo, extensionName: string, extensionType: IMessageType<T>): T | undefined;
export {};
