From 3e2b2a9996a867293934f1c9417a6f70949b7ee9 Mon Sep 17 00:00:00 2001 From: Konstantin Olkhovskiy Date: Tue, 11 Jun 2024 10:52:40 +0400 Subject: [PATCH 1/2] Fix compilation of option_processing.proto --- src/tests/expectation/dune | 7 +++++++ src/tests/expectation/it_compiles.ml | 3 +++ .../expectation/option_processing.ml.expected | 16 ++++++++-------- src/tests/expectation/option_processing.proto | 2 +- 4 files changed, 19 insertions(+), 9 deletions(-) create mode 100644 src/tests/expectation/it_compiles.ml diff --git a/src/tests/expectation/dune b/src/tests/expectation/dune index 0912187d..47a5edc8 100644 --- a/src/tests/expectation/dune +++ b/src/tests/expectation/dune @@ -12,6 +12,13 @@ (package ocaml-protoc) (flags :standard -open Ocaml_protoc_compiler_lib)) +(test + (name it_compiles) + (modules It_compiles Option_processing) + (libraries pbrt ocaml-protoc.compiler-lib) + (package ocaml-protoc) + (flags :standard -open Ocaml_protoc_compiler_lib)) + (rule (targets option_processing.ml option_processing.mli) (deps option_processing.proto) diff --git a/src/tests/expectation/it_compiles.ml b/src/tests/expectation/it_compiles.ml new file mode 100644 index 00000000..844e98a6 --- /dev/null +++ b/src/tests/expectation/it_compiles.ml @@ -0,0 +1,3 @@ +[@@@warning "-66"] + +open! Option_processing diff --git a/src/tests/expectation/option_processing.ml.expected b/src/tests/expectation/option_processing.ml.expected index 72bc09b8..95634a35 100644 --- a/src/tests/expectation/option_processing.ml.expected +++ b/src/tests/expectation/option_processing.ml.expected @@ -11,7 +11,7 @@ type person_location = { lng : float; } -type person_id = +type person_xyz = | X of string | Y of int32 | Z of float @@ -22,7 +22,7 @@ and person = { name : string; home : person_location option; picture : bytes; - id : person_id option; + xyz : person_xyz option; } type destructured_options = unit @@ -37,7 +37,7 @@ let rec default_person_location lng; } -let rec default_person_id () : person_id = X ("") +let rec default_person_xyz () : person_xyz = X ("") and default_person ?id:((id:int64) = 0L) @@ -45,14 +45,14 @@ and default_person ?name:((name:string) = "") ?home:((home:person_location option) = None) ?picture:((picture:bytes) = Bytes.create 0) - ?id:((id:person_id option) = None) + ?xyz:((xyz:person_xyz option) = None) () : person = { id; email; name; home; picture; - id; + xyz; } let rec default_destructured_options = () @@ -112,7 +112,7 @@ let rec default_destructured_options = () (* ----------------------------------------------------- *) (* Module Prefix: Option_processing - Variant: person_id + Variant: person_xyz Constructor: X Field Type: Vct_non_nullary_constructor: Ft_basic_type: Bt_string @@ -166,8 +166,8 @@ let rec default_destructured_options = () "bar", "baz"]}} }] - - Field: id - Rft_variant: person_id + - Field: xyz + Rft_variant: person_xyz Field options: [{ "(validate.required)": true }] diff --git a/src/tests/expectation/option_processing.proto b/src/tests/expectation/option_processing.proto index 8aae5c13..c7af9c19 100644 --- a/src/tests/expectation/option_processing.proto +++ b/src/tests/expectation/option_processing.proto @@ -32,7 +32,7 @@ message Person { bytes picture = 5 [(validate.rules).bytes = {not_in: ["foo", "bar", "baz"]}]; - oneof id { + oneof xyz { option (validate.required) = true; string x = 6 [(validate.rules).string.prefix = "foo"]; From 53bcc4736937ff9c35ffc2a9803865a1f22c4963 Mon Sep 17 00:00:00 2001 From: Konstantin Olkhovskiy Date: Tue, 11 Jun 2024 10:21:42 +0400 Subject: [PATCH 2/2] Parsing of Pb_options according to protobuf schema --- src/compilerlib/dune | 11 +- .../pb_codegen_decode_pb_options.ml | 346 +++ .../pb_codegen_decode_pb_options.mli | 5 + src/ocaml-protoc/ocaml_protoc_cmdline.ml | 6 + src/ocaml-protoc/ocaml_protoc_generation.ml | 4 + src/runtime-pb-options/dune | 6 + src/runtime-pb-options/pbrt_pb_options.ml | 147 + src/runtime-pb-options/pbrt_pb_options.mli | 34 + src/tests/expectation/dune | 18 + .../test_decode_pb_options.expected | 87 + .../expectation/test_decode_pb_options.ml | 74 + src/tests/expectation/validate.ml.expected | 2480 +++++++++++++++++ src/tests/expectation/validate.proto | 883 ++++++ 13 files changed, 4096 insertions(+), 5 deletions(-) create mode 100644 src/compilerlib/pb_codegen_decode_pb_options.ml create mode 100644 src/compilerlib/pb_codegen_decode_pb_options.mli create mode 100644 src/runtime-pb-options/dune create mode 100644 src/runtime-pb-options/pbrt_pb_options.ml create mode 100644 src/runtime-pb-options/pbrt_pb_options.mli create mode 100644 src/tests/expectation/test_decode_pb_options.expected create mode 100644 src/tests/expectation/test_decode_pb_options.ml create mode 100644 src/tests/expectation/validate.ml.expected create mode 100644 src/tests/expectation/validate.proto diff --git a/src/compilerlib/dune b/src/compilerlib/dune index 8a8acde4..d0cd6229 100644 --- a/src/compilerlib/dune +++ b/src/compilerlib/dune @@ -13,9 +13,10 @@ pb_codegen_make pb_codegen_encode_binary pb_codegen_encode_bs pb_codegen_encode_yojson pb_codegen_formatting pb_codegen_ocaml_type_dump pb_codegen_ocaml_type pb_codegen_pp pb_codegen_plugin pb_codegen_types - pb_codegen_services pb_codegen_util pb_exception pb_field_type pb_location - pb_logger pb_option pb_raw_option pb_parsing pb_parsing_lexer - pb_parsing_parser pb_parsing_parse_tree pb_parsing_util pb_typing_graph - pb_typing pb_typing_recursion pb_typing_resolution pb_typing_type_tree - pb_typing_util pb_typing_validation pb_util pb_format_util) + Pb_codegen_decode_pb_options pb_codegen_services pb_codegen_util + pb_exception pb_field_type pb_location pb_logger pb_option pb_raw_option + pb_parsing pb_parsing_lexer pb_parsing_parser pb_parsing_parse_tree + pb_parsing_util pb_typing_graph pb_typing pb_typing_recursion + pb_typing_resolution pb_typing_type_tree pb_typing_util + pb_typing_validation pb_util pb_format_util) (libraries stdlib-shims)) diff --git a/src/compilerlib/pb_codegen_decode_pb_options.ml b/src/compilerlib/pb_codegen_decode_pb_options.ml new file mode 100644 index 00000000..5278ea4b --- /dev/null +++ b/src/compilerlib/pb_codegen_decode_pb_options.ml @@ -0,0 +1,346 @@ +module Ot = Pb_codegen_ocaml_type +module F = Pb_codegen_formatting + +let sp = Pb_codegen_util.sp + +let field_pattern_match ~r_name ~rf_label field_type = + match field_type with + | Ot.Ft_basic_type bt -> + let decode runtime_f = + sp "Pbrt_pb_options.%s pb_options_value \"%s\" \"%s\"" runtime_f r_name + rf_label + in + let exp = + match bt with + | Ot.Bt_string -> decode "string" + | Ot.Bt_float -> decode "float" + | Ot.Bt_int -> decode "int" + | Ot.Bt_int32 -> decode "int32" + | Ot.Bt_int64 -> decode "int64" + | Ot.Bt_uint32 -> sp "`unsigned (%s)" (decode "int32") + | Ot.Bt_uint64 -> sp "`unsigned (%s)" (decode "int64") + | Ot.Bt_bool -> decode "bool" + | Ot.Bt_bytes -> decode "bytes" + in + "pb_options_value", exp + | Ot.Ft_unit -> + ( "pb_options_value", + sp "Pbrt_pb_options.unit pb_options_value \"%s\" \"%s\"" r_name rf_label ) + | Ot.Ft_user_defined_type udt -> + let f_name = + let function_prefix = "decode_pb_options" in + Pb_codegen_util.function_name_of_user_defined ~function_prefix udt + in + let value_expression = "(" ^ f_name ^ " pb_options_value)" in + "pb_options_value", value_expression + | _ -> assert false + +let pb_options_label_of_field_label rf_label = + match rf_label with + | "and_" | "as_" | "assert_" | "begin_" | "class_" | "constraint_" | "do_" + | "done_" | "downto_" | "else_" | "end_" | "exception_" | "external_" + | "false_" | "for_" | "fun_" | "function_" | "functor_" | "if_" | "in_" + | "include_" | "inherit_" | "initializer_" | "lazy_" | "let_" | "match_" + | "method_" | "module_" | "mutable_" | "new_" | "nonrec_" | "object_" | "of_" + | "open_" | "or_" | "private_" | "rec_" | "sig_" | "struct_" | "then_" | "to_" + | "true_" | "try_" | "type_" | "unit_" | "val_" | "virtual_" | "when_" + | "while_" | "with_" | "mod_" | "land_" | "lor_" | "lxor_" | "lsl_" | "lsr_" + | "asr_" -> + String.sub rf_label 0 (String.length rf_label - 1) + | _ -> rf_label + +(* Generate all the pattern matches for a record field *) +let gen_rft_nolabel sc ~r_name ~rf_label (field_type, _, _) = + let pb_options_label = pb_options_label_of_field_label rf_label in + + let match_variable_name, exp = + field_pattern_match ~r_name ~rf_label field_type + in + F.linep sc "| (\"%s\", %s) -> " pb_options_label match_variable_name; + F.linep sc " v.%s <- %s" rf_label exp + +(* Generate all the pattern matches for a repeated field *) +let gen_rft_repeated_field sc ~r_name ~rf_label repeated_field = + let _, field_type, _, _, _ = repeated_field in + + let pb_options_label = pb_options_label_of_field_label rf_label in + + F.linep sc + "| (\"%s\", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin" + pb_options_label; + + F.sub_scope sc (fun sc -> + F.linep sc "v.%s <- List.map (function" rf_label; + let match_variable_name, exp = + field_pattern_match ~r_name ~rf_label field_type + in + F.linep sc " | %s -> %s" match_variable_name exp; + F.line sc ") l;"); + + F.line sc "end" + +let gen_rft_optional_field sc ~r_name ~rf_label optional_field = + let field_type, _, _, _ = optional_field in + + let pb_options_label = pb_options_label_of_field_label rf_label in + + let match_variable_name, exp = + field_pattern_match ~r_name ~rf_label field_type + in + + F.linep sc "| (\"%s\", %s) -> " pb_options_label match_variable_name; + F.linep sc " v.%s <- Some (%s)" rf_label exp + +(* Generate pattern match for a variant field *) +let gen_rft_variant_field sc ~r_name ~rf_label { Ot.v_constructors; _ } = + List.iter + (fun { Ot.vc_constructor; vc_field_type; _ } -> + let pb_options_label = + Pb_codegen_util.camel_case_of_constructor vc_constructor + in + + match vc_field_type with + | Ot.Vct_nullary -> + F.linep sc "| (\"%s\", _) -> v.%s <- Some %s" pb_options_label rf_label + vc_constructor + | Ot.Vct_non_nullary_constructor field_type -> + let match_variable_name, exp = + field_pattern_match ~r_name ~rf_label field_type + in + F.linep sc "| (\"%s\", %s) -> " pb_options_label match_variable_name; + F.linep sc " v.%s <- Some (%s (%s))" rf_label vc_constructor exp) + v_constructors + +let gen_rft_assoc_field sc ~r_name ~rf_label ~assoc_type ~key_type ~value_type = + let pb_options_label = pb_options_label_of_field_label rf_label in + F.linep sc + "| (\"%s\", Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc) ->" + pb_options_label; + F.sub_scope sc (fun sc -> + let value_name, value_exp = + field_pattern_match ~r_name ~rf_label value_type + in + let key_name = "key" in + let key_exp = + match key_type with + | Ot.Bt_string -> "key" + | Ot.Bt_int -> "(Int.of_string key)" + | Ot.Bt_int32 -> "(Int32.of_string key)" + | Ot.Bt_int64 -> "(Int64.of_string key)" + | Ot.Bt_uint32 -> "(`unsigned (Int32.of_string key))" + | Ot.Bt_uint64 -> "(`unsigned (Int64.of_string key))" + | Ot.Bt_bool -> "(Bool.of_string key)" + | Ot.Bt_float -> + Printf.eprintf "float cannot be used as a map key type"; + exit 1 + | Ot.Bt_bytes -> + Printf.eprintf "bytes cannot be used as a map key type"; + exit 1 + in + F.line sc "let assoc ="; + F.sub_scope sc (fun sc -> + F.line sc "assoc"; + F.linep sc "|> List.map (fun (%s, %s) -> (%s, %s)) " key_name + value_name key_exp value_exp; + F.line sc "|> List.to_seq"; + (* Passing through [Hashtbl.of_seq] even in the [At_list] case ensures that if there + is a repeated key we take the last value associated with it. *) + F.line sc "|> Hashtbl.of_seq"); + F.line sc "in"; + let assoc_exp = + match assoc_type with + | Ot.At_hashtable -> "assoc" + | Ot.At_list -> "assoc |> Hashtbl.to_seq |> List.of_seq" + in + F.linep sc "v.%s <- %s" rf_label assoc_exp) + +(* Generate decode function for a record *) +let gen_record ?and_ { Ot.r_name; r_fields } sc = + let mutable_record_name = Pb_codegen_util.mutable_record_name r_name in + + F.line sc + @@ sp "%s decode_pb_options_%s d =" + (Pb_codegen_util.let_decl_of_and and_) + r_name; + + F.sub_scope sc (fun sc -> + F.linep sc "let v = default_%s () in" mutable_record_name; + F.line sc @@ "let assoc = match d with"; + F.line sc + @@ " | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> \ + assoc"; + F.line sc @@ " | _ -> assert(false)"; + (* TODO raise E *) + F.line sc @@ "in"; + + F.line sc "List.iter (function "; + F.sub_scope sc (fun sc -> + (* Generate pattern match for all the possible message field *) + List.iter + (fun { Ot.rf_label; rf_field_type; _ } -> + match rf_field_type with + | Ot.Rft_nolabel nolabel_field -> + gen_rft_nolabel sc ~r_name ~rf_label nolabel_field + | Ot.Rft_repeated repeated_field -> + gen_rft_repeated_field sc ~r_name ~rf_label repeated_field + | Ot.Rft_variant variant_field -> + gen_rft_variant_field sc ~r_name ~rf_label variant_field + | Ot.Rft_optional optional_field -> + gen_rft_optional_field sc ~r_name ~rf_label optional_field + | Ot.Rft_required _ -> + Printf.eprintf + "Only proto3 syntax supported in pb_options encoding"; + exit 1 + | Ot.Rft_associative + (assoc_type, _, (key_type, _), (value_type, _)) -> + gen_rft_assoc_field sc ~r_name ~rf_label ~assoc_type ~key_type + ~value_type) + r_fields; + + (* Unknown fields are simply ignored *) + F.empty_line sc; + F.line sc "| (_, _) -> () (*Unknown fields are ignored*)"); + F.line sc ") assoc;"; + + (* Transform the mutable record in an immutable one *) + F.line sc "({"; + F.sub_scope sc (fun sc -> + List.iter + (fun { Ot.rf_label; _ } -> + F.linep sc "%s = v.%s;" rf_label rf_label) + r_fields); + F.linep sc "} : %s)" r_name) + +(* Generate decode function for an empty record *) +let gen_unit ?and_ { Ot.er_name } sc = + F.line sc + @@ sp "%s decode_pb_options_%s d =" + (Pb_codegen_util.let_decl_of_and and_) + er_name; + F.line sc (sp "Pbrt_pb_options.unit d \"%s\" \"%s\"" er_name "empty record") + +(* Generate decode function for a variant type *) +let gen_variant ?and_ { Ot.v_name; v_constructors } sc = + (* helper function for each constructor case *) + let process_v_constructor sc { Ot.vc_constructor; vc_field_type; _ } = + let pb_options_label = + Pb_codegen_util.camel_case_of_constructor vc_constructor + in + + match vc_field_type with + | Ot.Vct_nullary -> + F.linep sc "| (\"%s\", _)::_-> (%s : %s)" pb_options_label vc_constructor + v_name + | Ot.Vct_non_nullary_constructor field_type -> + let match_, exp = + let r_name = v_name and rf_label = vc_constructor in + field_pattern_match ~r_name ~rf_label field_type + in + + F.linep sc "| (\"%s\", %s)::_ -> " pb_options_label match_; + F.linep sc " (%s (%s) : %s)" vc_constructor exp v_name + in + + F.linep sc "%s decode_pb_options_%s pb_options =" + (Pb_codegen_util.let_decl_of_and and_) + v_name; + + F.sub_scope sc (fun sc -> + (* even though a variant should be an object with a single field, + * it is possible other fields are present in the pb_options object. Therefore + * we still need a loop to iterate over the key/value, even if in 99.99% + * of the cases it will be a single iteration *) + F.line sc "let assoc = match pb_options with"; + F.line sc + " | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc"; + F.line sc " | _ -> assert(false)"; + (* TODO raise E *) + F.line sc "in"; + + F.line sc "let rec loop = function"; + F.sub_scope sc (fun sc -> + (* termination condition *) + F.linep sc "| [] -> Pbrt_pb_options.E.malformed_variant \"%s\"" v_name; + + List.iter (process_v_constructor sc) v_constructors; + + F.empty_line sc; + F.line sc "| _ :: tl -> loop tl"); + F.line sc "in"; + F.line sc "loop assoc") + +let gen_const_variant ?and_ { Ot.cv_name; cv_constructors } sc = + F.linep sc "%s decode_pb_options_%s pb_options =" + (Pb_codegen_util.let_decl_of_and and_) + cv_name; + + F.sub_scope sc (fun sc -> + F.line sc "match pb_options with"; + List.iter + (fun { Ot.cvc_name; cvc_string_value; _ } -> + F.linep sc + "| Ocaml_protoc_compiler_lib.Pb_option.Scalar_value \ + (Constant_literal \"%s\") -> (%s : %s)" + cvc_string_value cvc_name cv_name) + cv_constructors; + F.linep sc "| _ -> Pbrt_pb_options.E.malformed_variant \"%s\"" cv_name) + +let gen_struct ?and_ t sc = + let { Ot.spec; _ } = t in + let has_encoded = + match spec with + | Ot.Record r -> + gen_record ?and_ r sc; + true + | Ot.Variant v -> + gen_variant ?and_ v sc; + true + | Ot.Const_variant v -> + gen_const_variant ?and_ v sc; + true + | Ot.Unit u -> + gen_unit ?and_ u sc; + true + in + has_encoded + +let gen_sig ?and_ t sc = + let _ = and_ in + let { Ot.spec; _ } = t in + + let f type_name = + F.linep sc + "val decode_pb_options_%s : Ocaml_protoc_compiler_lib.Pb_option.value -> \ + %s" + type_name type_name; + F.linep sc + ("(** [decode_pb_options_%s decoder] decodes a " + ^^ "[%s] value from [decoder] *)") + type_name type_name + in + + match spec with + | Ot.Record { Ot.r_name; _ } -> + f r_name; + true + | Ot.Variant { Ot.v_name; _ } -> + f v_name; + true + | Ot.Const_variant { Ot.cv_name; _ } -> + f cv_name; + true + | Ot.Unit { Ot.er_name; _ } -> + f er_name; + true + +let ocamldoc_title = "Pb_option.set Decoding" +let requires_mutable_records = true + +let plugin : Pb_codegen_plugin.t = + let module P = struct + let gen_sig = gen_sig + let gen_struct = gen_struct + let ocamldoc_title = ocamldoc_title + let requires_mutable_records = requires_mutable_records + end in + (module P) diff --git a/src/compilerlib/pb_codegen_decode_pb_options.mli b/src/compilerlib/pb_codegen_decode_pb_options.mli new file mode 100644 index 00000000..6f01a688 --- /dev/null +++ b/src/compilerlib/pb_codegen_decode_pb_options.mli @@ -0,0 +1,5 @@ +(** Code generator to decode messages from protobuf message options *) + +include Pb_codegen_plugin.S + +val plugin : Pb_codegen_plugin.t diff --git a/src/ocaml-protoc/ocaml_protoc_cmdline.ml b/src/ocaml-protoc/ocaml_protoc_cmdline.ml index d33a0141..f665f04a 100644 --- a/src/ocaml-protoc/ocaml_protoc_cmdline.ml +++ b/src/ocaml-protoc/ocaml_protoc_cmdline.ml @@ -114,6 +114,8 @@ module Cmdline = struct pp: bool ref; (** whether pretty printing is enabled *) dump_type_repr: bool ref; (** whether comments with debug ocaml type representation are added *) + pb_options: bool ref; + (** generate decoding for protobuf options (protobuf text format) *) services: bool ref; (** whether services code generation is enabled *) make: bool ref; (** whether to generate "make" functions *) mutable cmd_line_file_options: File_options.t; @@ -134,6 +136,7 @@ module Cmdline = struct bs = ref false; pp = ref false; dump_type_repr = ref false; + pb_options = ref false; services = ref false; make = ref false; cmd_line_file_options = File_options.make (); @@ -150,6 +153,9 @@ module Cmdline = struct Arg.Set t.dump_type_repr, " generate comments with internal representation on generated OCaml \ types (useful for debugging ocaml-protoc itself)" ); + ( "--pb_options", + Arg.Set t.pb_options, + " generate decoders for protobuf options (proto text format)" ); ( "--services", Arg.Set t.services, " generate code for services (requires json+binary)" ); diff --git a/src/ocaml-protoc/ocaml_protoc_generation.ml b/src/ocaml-protoc/ocaml_protoc_generation.ml index a1cc999b..e7d55a2f 100644 --- a/src/ocaml-protoc/ocaml_protoc_generation.ml +++ b/src/ocaml-protoc/ocaml_protoc_generation.ml @@ -60,6 +60,10 @@ let generate_code ocaml_types ~proto_file_options cmdline : unit = [ Pb_codegen_ocaml_type_dump.plugin ] else []); + (if !(cmdline.Cmdline.pb_options) then + [ Pb_codegen_decode_pb_options.plugin ] + else + []); (if !(cmdline.Cmdline.pp) then [ Pb_codegen_pp.plugin ] else diff --git a/src/runtime-pb-options/dune b/src/runtime-pb-options/dune new file mode 100644 index 00000000..f62703c0 --- /dev/null +++ b/src/runtime-pb-options/dune @@ -0,0 +1,6 @@ +(library + (name pbrt_pb_options) + (public_name ocaml-protoc.rt-pb-options) + (wrapped false) + (libraries + (re_export ocaml-protoc.compiler-lib))) diff --git a/src/runtime-pb-options/pbrt_pb_options.ml b/src/runtime-pb-options/pbrt_pb_options.ml new file mode 100644 index 00000000..2bdd18ff --- /dev/null +++ b/src/runtime-pb-options/pbrt_pb_options.ml @@ -0,0 +1,147 @@ +module E = struct + type error = + | Unexpected_option_type of string * string + | Malformed_variant of string + + exception Failure of error + + let unexpected_option_type record_name field_name = + raise (Failure (Unexpected_option_type (record_name, field_name))) + + let malformed_variant variant_name = + raise (Failure (Malformed_variant variant_name)) + + let string_of_error = function + | Unexpected_option_type (record_name, field_name) -> + Printf.sprintf "Unexpected option type (record name:%s, field_name:%s)" + record_name field_name + | Malformed_variant variant_name -> + Printf.sprintf "Malformed variant (variant name: %s)" variant_name + + let () = + Printexc.register_printer (fun exn -> + match exn with + | Failure e -> Some (string_of_error e) + | _ -> None) +end + +open Ocaml_protoc_compiler_lib + +let unescape_string str = + let buffer = Buffer.create (String.length str) in + let rec aux i = + if i < String.length str then ( + match str.[i] with + | '\\' -> + (match str.[i + 1] with + | 'a' -> + Buffer.add_char buffer '\007'; + aux (i + 2) + | 'b' -> + Buffer.add_char buffer '\b'; + aux (i + 2) + | 'f' -> + Buffer.add_char buffer '\012'; + aux (i + 2) + | 'n' -> + Buffer.add_char buffer '\n'; + aux (i + 2) + | 'r' -> + Buffer.add_char buffer '\r'; + aux (i + 2) + | 't' -> + Buffer.add_char buffer '\t'; + aux (i + 2) + | 'v' -> + Buffer.add_char buffer '\011'; + aux (i + 2) + | '?' -> + Buffer.add_char buffer '?'; + aux (i + 2) + | '\\' -> + Buffer.add_char buffer '\\'; + aux (i + 2) + | '\'' -> + Buffer.add_char buffer '\''; + aux (i + 2) + | '"' -> + Buffer.add_char buffer '"'; + aux (i + 2) + | 'x' -> + (* handle hexadecimal escape *) + let hex = String.sub str (i + 2) 2 in + Buffer.add_char buffer (Char.chr (int_of_string ("0x" ^ hex))); + aux (i + 4) + | 'u' -> + (* handle Unicode escape with 4 hex digits *) + let unicode = String.sub str (i + 2) 4 in + Buffer.add_char buffer (Char.chr (int_of_string ("0x" ^ unicode))); + aux (i + 6) + | 'U' -> + (* handle Unicode escape with 5 hex digits *) + let unicode = String.sub str (i + 2) 5 in + Buffer.add_char buffer (Char.chr (int_of_string ("0x" ^ unicode))); + aux (i + 7) + | c when c >= '0' && c <= '7' -> + (* handle octal escape *) + let end_idx = min (i + 4) (String.length str) in + let rec find_octal_end idx = + if idx < end_idx && str.[idx] >= '0' && str.[idx] <= '7' then + find_octal_end (idx + 1) + else + idx + in + let octal_end = find_octal_end (i + 2) in + let octal = String.sub str (i + 1) (octal_end - i - 1) in + Buffer.add_char buffer (Char.chr (int_of_string ("0o" ^ octal))); + aux octal_end + | c -> failwith (Printf.sprintf "Invalid escape sequence: \\%c" c)) + | c -> + Buffer.add_char buffer c; + aux (i + 1) + ) + in + aux 0; + Buffer.contents buffer + +let int32 v record_name field_name = + match v with + | Pb_option.Scalar_value (Constant_float v) -> Int32.of_float v + | Pb_option.Scalar_value (Constant_int v) -> Int32.of_int v + | _ -> E.unexpected_option_type record_name field_name + +let float v record_name field_name = + match v with + | Pb_option.Scalar_value (Constant_float v) -> v + | Pb_option.Scalar_value (Constant_int v) -> float_of_int v + | _ -> E.unexpected_option_type record_name field_name + +let int64 v record_name field_name = + match v with + | Pb_option.Scalar_value (Constant_float v) -> Int64.of_float v + | Pb_option.Scalar_value (Constant_int v) -> Int64.of_int v + | _ -> E.unexpected_option_type record_name field_name + +let int v record_name field_name = + match v with + | Pb_option.Scalar_value (Constant_float v) -> int_of_float v + | Pb_option.Scalar_value (Constant_int v) -> v + | _ -> E.unexpected_option_type record_name field_name + +let string v record_name field_name = + match v with + | Pb_option.Scalar_value (Constant_string v) -> unescape_string v + | _ -> E.unexpected_option_type record_name field_name + +let bool v record_name field_name = + match v with + | Pb_option.Scalar_value (Constant_bool v) -> v + | _ -> E.unexpected_option_type record_name field_name + +let bytes v record_name field_name = + string v record_name field_name |> Bytes.of_string + +let unit v record_name field_name = + match v with + | Pb_option.Message_literal [] -> () + | _ -> E.unexpected_option_type record_name field_name diff --git a/src/runtime-pb-options/pbrt_pb_options.mli b/src/runtime-pb-options/pbrt_pb_options.mli new file mode 100644 index 00000000..062dff7a --- /dev/null +++ b/src/runtime-pb-options/pbrt_pb_options.mli @@ -0,0 +1,34 @@ +(** Protobuf JSON encoding runtime *) + +(** All exception which could be raised by the generated JSON encoder + and decode function *) +module E : sig + type error = + | Unexpected_option_type of string * string + | Malformed_variant of string + + exception Failure of error + (** Decoding/Encoding failure *) + + val unexpected_option_type : string -> string -> 'a + (** [unexpected_option_type record_name field_name] raises + [Failure (Unexpected_json_type (record_name, field_name))] *) + + val malformed_variant : string -> 'a + (** [malformed_variant variant_name] raise + [Failure (Malformed_variant variant_name)] *) +end + +open Ocaml_protoc_compiler_lib + +(** Helper module for the generated code for common + functionality *) + +val string : Pb_option.value -> string -> string -> string +val float : Pb_option.value -> string -> string -> float +val int32 : Pb_option.value -> string -> string -> int32 +val int64 : Pb_option.value -> string -> string -> int64 +val int : Pb_option.value -> string -> string -> int +val bool : Pb_option.value -> string -> string -> bool +val bytes : Pb_option.value -> string -> string -> bytes +val unit : Pb_option.value -> string -> string -> unit diff --git a/src/tests/expectation/dune b/src/tests/expectation/dune index 47a5edc8..75676633 100644 --- a/src/tests/expectation/dune +++ b/src/tests/expectation/dune @@ -19,6 +19,13 @@ (package ocaml-protoc) (flags :standard -open Ocaml_protoc_compiler_lib)) +(test + (name test_decode_pb_options) + (libraries pbrt ocaml-protoc.compiler-lib ocaml-protoc.rt-pb-options) + (package ocaml-protoc) + (flags :standard -open Ocaml_protoc_compiler_lib) + (modules Test_decode_pb_options Validate)) + (rule (targets option_processing.ml option_processing.mli) (deps option_processing.proto) @@ -29,3 +36,14 @@ (alias runtest) (action (diff option_processing.ml.expected option_processing.ml))) + +(rule + (targets validate.ml validate.mli) + (deps validate.proto) + (action + (run ocaml-protoc --pb_options --pp --ml_out ./ %{deps}))) + +(rule + (alias runtest) + (action + (diff validate.ml.expected validate.ml))) diff --git a/src/tests/expectation/test_decode_pb_options.expected b/src/tests/expectation/test_decode_pb_options.expected new file mode 100644 index 00000000..47bbcfd3 --- /dev/null +++ b/src/tests/expectation/test_decode_pb_options.expected @@ -0,0 +1,87 @@ +====================== ====================== +[{ + "(validate.rules)": {"uint64": {"gt": 999}} + }] +===================== ====================== +======================= ======================= +{ message = None; + type_ = Some(Uint64({ const = None; lt = None; lte = None; gt = Some(999); gte = None; in_ = []; not_in = []; ignore_empty = None; })); +} +====================== ======================= + + +====================== ====================== +[{ + "(validate.rules)": {"string": {"email": true}} + }] +===================== ====================== +======================= ======================= +{ message = None; + type_ = + Some( + String( + { const = None; + len = None; + min_len = None; + max_len = None; + len_bytes = None; + min_bytes = None; + max_bytes = None; + pattern = None; + prefix = None; + suffix = None; + contains = None; + not_contains = None; + in_ = []; + not_in = []; + well_known = Some(Email(true)); + strict = Some(true); + ignore_empty = None; + })); +} +====================== ======================= + + +====================== ====================== +[{ + "(validate.rules)": {"string": {"pattern": "^[^[0-9]A-Za-z]+( [^[0-9]A-Za-z]+)*$", + "max_bytes": 256}} + }] +===================== ====================== +======================= ======================= +{ message = None; + type_ = + Some( + String( + { const = None; + len = None; + min_len = None; + max_len = None; + len_bytes = None; + min_bytes = None; + max_bytes = Some(256); + pattern = Some("^[^[0-9]A-Za-z]+( [^[0-9]A-Za-z]+)*$"); + prefix = None; + suffix = None; + contains = None; + not_contains = None; + in_ = []; + not_in = []; + well_known = None; + strict = Some(true); + ignore_empty = None; + })); +} +====================== ======================= + + +====================== ====================== +[{ + "(validate.rules)": {"message": {"required": true}} + }] +===================== ====================== +======================= ======================= +{ message = Some({ skip = None; required = Some(true); }); type_ = None; } +====================== ======================= + + diff --git a/src/tests/expectation/test_decode_pb_options.ml b/src/tests/expectation/test_decode_pb_options.ml new file mode 100644 index 00000000..e36402b6 --- /dev/null +++ b/src/tests/expectation/test_decode_pb_options.ml @@ -0,0 +1,74 @@ +module E = Pb_exception +module Pt = Pb_parsing_parse_tree + +let process_field_options ppf field = + let options = + field.Pt.field_options |> Pb_typing_validation.compile_options + in + if options <> Pb_option.empty then ( + let parsed = + Pb_option.get_ext options "validate.rules" + |> Option.map Validate.decode_pb_options_field_rules + in + Format.fprintf ppf + "====================== \ + ======================@.%a@.===================== \ + ======================@.======================= \ + =======================@.%a@.====================== \ + =======================@.@.@." + Pb_option.pp_set options + (Format.pp_print_option Validate.pp_field_rules) + parsed; + () + ) + +let run proto = + let protos = + Pb_parsing.parse_file + (fun f -> + match f with + | "test.proto" -> f, proto + | _ -> f, "") + "test.proto" + in + let ppf = Format.std_formatter in + Format.set_margin 150; + protos + |> List.iter (fun proto -> + proto.Pt.messages + |> List.iter (fun message -> + message.Pt.message_body + |> List.iter (function + | Pt.Message_field field -> process_field_options ppf field + | _ -> ()))) + +let test_cases = + [ + {| + syntax = "proto3"; + + package examplepb; + + import "validate/validate.proto"; + + message Person { + uint64 id = 1 [(validate.rules).uint64.gt = 999]; + + string email = 2 [(validate.rules).string.email = true]; + + string name = 3 [(validate.rules).string = { + pattern: "^[^[0-9]A-Za-z]+( [^[0-9]A-Za-z]+)*$", + max_bytes: 256, + }]; + + Location home = 4 [(validate.rules).message.required = true]; + + message Location { + double lat = 1 [(validate.rules).double = {gte: -90, lte: 90}]; + double lng = 2 [(validate.rules).double = {gte: -180, lte: 180}]; + } + } + |}; + ] + +let () = List.iter run test_cases diff --git a/src/tests/expectation/validate.ml.expected b/src/tests/expectation/validate.ml.expected new file mode 100644 index 00000000..70e3fb0d --- /dev/null +++ b/src/tests/expectation/validate.ml.expected @@ -0,0 +1,2480 @@ +[@@@ocaml.warning "-27-30-39-44"] + +type message_options = { + disabled : bool option; + ignored : bool option; +} + +type oneof_options = { + required : bool option; +} + +type message_rules = { + skip : bool option; + required : bool option; +} + +type float_rules = { + const : float option; + lt : float option; + lte : float option; + gt : float option; + gte : float option; + in_ : float list; + not_in : float list; + ignore_empty : bool option; +} + +type double_rules = { + const : float option; + lt : float option; + lte : float option; + gt : float option; + gte : float option; + in_ : float list; + not_in : float list; + ignore_empty : bool option; +} + +type int32_rules = { + const : int32 option; + lt : int32 option; + lte : int32 option; + gt : int32 option; + gte : int32 option; + in_ : int32 list; + not_in : int32 list; + ignore_empty : bool option; +} + +type int64_rules = { + const : int64 option; + lt : int64 option; + lte : int64 option; + gt : int64 option; + gte : int64 option; + in_ : int64 list; + not_in : int64 list; + ignore_empty : bool option; +} + +type uint32_rules = { + const : int32 option; + lt : int32 option; + lte : int32 option; + gt : int32 option; + gte : int32 option; + in_ : int32 list; + not_in : int32 list; + ignore_empty : bool option; +} + +type uint64_rules = { + const : int64 option; + lt : int64 option; + lte : int64 option; + gt : int64 option; + gte : int64 option; + in_ : int64 list; + not_in : int64 list; + ignore_empty : bool option; +} + +type sint32_rules = { + const : int32 option; + lt : int32 option; + lte : int32 option; + gt : int32 option; + gte : int32 option; + in_ : int32 list; + not_in : int32 list; + ignore_empty : bool option; +} + +type sint64_rules = { + const : int64 option; + lt : int64 option; + lte : int64 option; + gt : int64 option; + gte : int64 option; + in_ : int64 list; + not_in : int64 list; + ignore_empty : bool option; +} + +type fixed32_rules = { + const : int32 option; + lt : int32 option; + lte : int32 option; + gt : int32 option; + gte : int32 option; + in_ : int32 list; + not_in : int32 list; + ignore_empty : bool option; +} + +type fixed64_rules = { + const : int64 option; + lt : int64 option; + lte : int64 option; + gt : int64 option; + gte : int64 option; + in_ : int64 list; + not_in : int64 list; + ignore_empty : bool option; +} + +type sfixed32_rules = { + const : int32 option; + lt : int32 option; + lte : int32 option; + gt : int32 option; + gte : int32 option; + in_ : int32 list; + not_in : int32 list; + ignore_empty : bool option; +} + +type sfixed64_rules = { + const : int64 option; + lt : int64 option; + lte : int64 option; + gt : int64 option; + gte : int64 option; + in_ : int64 list; + not_in : int64 list; + ignore_empty : bool option; +} + +type bool_rules = { + const : bool option; +} + +type known_regex = + | Unknown + | Http_header_name + | Http_header_value + +type string_rules_well_known = + | Email of bool + | Hostname of bool + | Ip of bool + | Ipv4 of bool + | Ipv6 of bool + | Uri of bool + | Uri_ref of bool + | Address of bool + | Uuid of bool + | Well_known_regex of known_regex + +and string_rules = { + const : string option; + len : int64 option; + min_len : int64 option; + max_len : int64 option; + len_bytes : int64 option; + min_bytes : int64 option; + max_bytes : int64 option; + pattern : string option; + prefix : string option; + suffix : string option; + contains : string option; + not_contains : string option; + in_ : string list; + not_in : string list; + well_known : string_rules_well_known option; + strict : bool option; + ignore_empty : bool option; +} + +type bytes_rules_well_known = + | Ip of bool + | Ipv4 of bool + | Ipv6 of bool + +and bytes_rules = { + const : bytes option; + len : int64 option; + min_len : int64 option; + max_len : int64 option; + pattern : string option; + prefix : bytes option; + suffix : bytes option; + contains : bytes option; + in_ : bytes list; + not_in : bytes list; + well_known : bytes_rules_well_known option; + ignore_empty : bool option; +} + +type enum_rules = { + const : int32 option; + defined_only : bool option; + in_ : int32 list; + not_in : int32 list; +} + +type any_rules = { + required : bool option; + in_ : string list; + not_in : string list; +} + +type field_rules_type = + | Float of float_rules + | Double of double_rules + | Int32 of int32_rules + | Int64 of int64_rules + | Uint32 of uint32_rules + | Uint64 of uint64_rules + | Sint32 of sint32_rules + | Sint64 of sint64_rules + | Fixed32 of fixed32_rules + | Fixed64 of fixed64_rules + | Sfixed32 of sfixed32_rules + | Sfixed64 of sfixed64_rules + | Bool of bool_rules + | String of string_rules + | Bytes of bytes_rules + | Enum of enum_rules + | Repeated of repeated_rules + | Map of map_rules + | Any of any_rules + +and field_rules = { + message : message_rules option; + type_ : field_rules_type option; +} + +and repeated_rules = { + min_items : int64 option; + max_items : int64 option; + unique : bool option; + items : field_rules option; + ignore_empty : bool option; +} + +and map_rules = { + min_pairs : int64 option; + max_pairs : int64 option; + no_sparse : bool option; + keys : field_rules option; + values : field_rules option; + ignore_empty : bool option; +} + +type field_options = { + rules : field_rules option; +} + +let rec default_message_options + ?disabled:((disabled:bool option) = None) + ?ignored:((ignored:bool option) = None) + () : message_options = { + disabled; + ignored; +} + +let rec default_oneof_options + ?required:((required:bool option) = None) + () : oneof_options = { + required; +} + +let rec default_message_rules + ?skip:((skip:bool option) = None) + ?required:((required:bool option) = None) + () : message_rules = { + skip; + required; +} + +let rec default_float_rules + ?const:((const:float option) = None) + ?lt:((lt:float option) = None) + ?lte:((lte:float option) = None) + ?gt:((gt:float option) = None) + ?gte:((gte:float option) = None) + ?in_:((in_:float list) = []) + ?not_in:((not_in:float list) = []) + ?ignore_empty:((ignore_empty:bool option) = None) + () : float_rules = { + const; + lt; + lte; + gt; + gte; + in_; + not_in; + ignore_empty; +} + +let rec default_double_rules + ?const:((const:float option) = None) + ?lt:((lt:float option) = None) + ?lte:((lte:float option) = None) + ?gt:((gt:float option) = None) + ?gte:((gte:float option) = None) + ?in_:((in_:float list) = []) + ?not_in:((not_in:float list) = []) + ?ignore_empty:((ignore_empty:bool option) = None) + () : double_rules = { + const; + lt; + lte; + gt; + gte; + in_; + not_in; + ignore_empty; +} + +let rec default_int32_rules + ?const:((const:int32 option) = None) + ?lt:((lt:int32 option) = None) + ?lte:((lte:int32 option) = None) + ?gt:((gt:int32 option) = None) + ?gte:((gte:int32 option) = None) + ?in_:((in_:int32 list) = []) + ?not_in:((not_in:int32 list) = []) + ?ignore_empty:((ignore_empty:bool option) = None) + () : int32_rules = { + const; + lt; + lte; + gt; + gte; + in_; + not_in; + ignore_empty; +} + +let rec default_int64_rules + ?const:((const:int64 option) = None) + ?lt:((lt:int64 option) = None) + ?lte:((lte:int64 option) = None) + ?gt:((gt:int64 option) = None) + ?gte:((gte:int64 option) = None) + ?in_:((in_:int64 list) = []) + ?not_in:((not_in:int64 list) = []) + ?ignore_empty:((ignore_empty:bool option) = None) + () : int64_rules = { + const; + lt; + lte; + gt; + gte; + in_; + not_in; + ignore_empty; +} + +let rec default_uint32_rules + ?const:((const:int32 option) = None) + ?lt:((lt:int32 option) = None) + ?lte:((lte:int32 option) = None) + ?gt:((gt:int32 option) = None) + ?gte:((gte:int32 option) = None) + ?in_:((in_:int32 list) = []) + ?not_in:((not_in:int32 list) = []) + ?ignore_empty:((ignore_empty:bool option) = None) + () : uint32_rules = { + const; + lt; + lte; + gt; + gte; + in_; + not_in; + ignore_empty; +} + +let rec default_uint64_rules + ?const:((const:int64 option) = None) + ?lt:((lt:int64 option) = None) + ?lte:((lte:int64 option) = None) + ?gt:((gt:int64 option) = None) + ?gte:((gte:int64 option) = None) + ?in_:((in_:int64 list) = []) + ?not_in:((not_in:int64 list) = []) + ?ignore_empty:((ignore_empty:bool option) = None) + () : uint64_rules = { + const; + lt; + lte; + gt; + gte; + in_; + not_in; + ignore_empty; +} + +let rec default_sint32_rules + ?const:((const:int32 option) = None) + ?lt:((lt:int32 option) = None) + ?lte:((lte:int32 option) = None) + ?gt:((gt:int32 option) = None) + ?gte:((gte:int32 option) = None) + ?in_:((in_:int32 list) = []) + ?not_in:((not_in:int32 list) = []) + ?ignore_empty:((ignore_empty:bool option) = None) + () : sint32_rules = { + const; + lt; + lte; + gt; + gte; + in_; + not_in; + ignore_empty; +} + +let rec default_sint64_rules + ?const:((const:int64 option) = None) + ?lt:((lt:int64 option) = None) + ?lte:((lte:int64 option) = None) + ?gt:((gt:int64 option) = None) + ?gte:((gte:int64 option) = None) + ?in_:((in_:int64 list) = []) + ?not_in:((not_in:int64 list) = []) + ?ignore_empty:((ignore_empty:bool option) = None) + () : sint64_rules = { + const; + lt; + lte; + gt; + gte; + in_; + not_in; + ignore_empty; +} + +let rec default_fixed32_rules + ?const:((const:int32 option) = None) + ?lt:((lt:int32 option) = None) + ?lte:((lte:int32 option) = None) + ?gt:((gt:int32 option) = None) + ?gte:((gte:int32 option) = None) + ?in_:((in_:int32 list) = []) + ?not_in:((not_in:int32 list) = []) + ?ignore_empty:((ignore_empty:bool option) = None) + () : fixed32_rules = { + const; + lt; + lte; + gt; + gte; + in_; + not_in; + ignore_empty; +} + +let rec default_fixed64_rules + ?const:((const:int64 option) = None) + ?lt:((lt:int64 option) = None) + ?lte:((lte:int64 option) = None) + ?gt:((gt:int64 option) = None) + ?gte:((gte:int64 option) = None) + ?in_:((in_:int64 list) = []) + ?not_in:((not_in:int64 list) = []) + ?ignore_empty:((ignore_empty:bool option) = None) + () : fixed64_rules = { + const; + lt; + lte; + gt; + gte; + in_; + not_in; + ignore_empty; +} + +let rec default_sfixed32_rules + ?const:((const:int32 option) = None) + ?lt:((lt:int32 option) = None) + ?lte:((lte:int32 option) = None) + ?gt:((gt:int32 option) = None) + ?gte:((gte:int32 option) = None) + ?in_:((in_:int32 list) = []) + ?not_in:((not_in:int32 list) = []) + ?ignore_empty:((ignore_empty:bool option) = None) + () : sfixed32_rules = { + const; + lt; + lte; + gt; + gte; + in_; + not_in; + ignore_empty; +} + +let rec default_sfixed64_rules + ?const:((const:int64 option) = None) + ?lt:((lt:int64 option) = None) + ?lte:((lte:int64 option) = None) + ?gt:((gt:int64 option) = None) + ?gte:((gte:int64 option) = None) + ?in_:((in_:int64 list) = []) + ?not_in:((not_in:int64 list) = []) + ?ignore_empty:((ignore_empty:bool option) = None) + () : sfixed64_rules = { + const; + lt; + lte; + gt; + gte; + in_; + not_in; + ignore_empty; +} + +let rec default_bool_rules + ?const:((const:bool option) = None) + () : bool_rules = { + const; +} + +let rec default_known_regex () = (Unknown:known_regex) + +let rec default_string_rules_well_known () : string_rules_well_known = Email (false) + +and default_string_rules + ?const:((const:string option) = None) + ?len:((len:int64 option) = None) + ?min_len:((min_len:int64 option) = None) + ?max_len:((max_len:int64 option) = None) + ?len_bytes:((len_bytes:int64 option) = None) + ?min_bytes:((min_bytes:int64 option) = None) + ?max_bytes:((max_bytes:int64 option) = None) + ?pattern:((pattern:string option) = None) + ?prefix:((prefix:string option) = None) + ?suffix:((suffix:string option) = None) + ?contains:((contains:string option) = None) + ?not_contains:((not_contains:string option) = None) + ?in_:((in_:string list) = []) + ?not_in:((not_in:string list) = []) + ?well_known:((well_known:string_rules_well_known option) = None) + ?strict:((strict:bool option) = Some (true)) + ?ignore_empty:((ignore_empty:bool option) = None) + () : string_rules = { + const; + len; + min_len; + max_len; + len_bytes; + min_bytes; + max_bytes; + pattern; + prefix; + suffix; + contains; + not_contains; + in_; + not_in; + well_known; + strict; + ignore_empty; +} + +let rec default_bytes_rules_well_known () : bytes_rules_well_known = Ip (false) + +and default_bytes_rules + ?const:((const:bytes option) = None) + ?len:((len:int64 option) = None) + ?min_len:((min_len:int64 option) = None) + ?max_len:((max_len:int64 option) = None) + ?pattern:((pattern:string option) = None) + ?prefix:((prefix:bytes option) = None) + ?suffix:((suffix:bytes option) = None) + ?contains:((contains:bytes option) = None) + ?in_:((in_:bytes list) = []) + ?not_in:((not_in:bytes list) = []) + ?well_known:((well_known:bytes_rules_well_known option) = None) + ?ignore_empty:((ignore_empty:bool option) = None) + () : bytes_rules = { + const; + len; + min_len; + max_len; + pattern; + prefix; + suffix; + contains; + in_; + not_in; + well_known; + ignore_empty; +} + +let rec default_enum_rules + ?const:((const:int32 option) = None) + ?defined_only:((defined_only:bool option) = None) + ?in_:((in_:int32 list) = []) + ?not_in:((not_in:int32 list) = []) + () : enum_rules = { + const; + defined_only; + in_; + not_in; +} + +let rec default_any_rules + ?required:((required:bool option) = None) + ?in_:((in_:string list) = []) + ?not_in:((not_in:string list) = []) + () : any_rules = { + required; + in_; + not_in; +} + +let rec default_field_rules_type () : field_rules_type = Float (default_float_rules ()) + +and default_field_rules + ?message:((message:message_rules option) = None) + ?type_:((type_:field_rules_type option) = None) + () : field_rules = { + message; + type_; +} + +and default_repeated_rules + ?min_items:((min_items:int64 option) = None) + ?max_items:((max_items:int64 option) = None) + ?unique:((unique:bool option) = None) + ?items:((items:field_rules option) = None) + ?ignore_empty:((ignore_empty:bool option) = None) + () : repeated_rules = { + min_items; + max_items; + unique; + items; + ignore_empty; +} + +and default_map_rules + ?min_pairs:((min_pairs:int64 option) = None) + ?max_pairs:((max_pairs:int64 option) = None) + ?no_sparse:((no_sparse:bool option) = None) + ?keys:((keys:field_rules option) = None) + ?values:((values:field_rules option) = None) + ?ignore_empty:((ignore_empty:bool option) = None) + () : map_rules = { + min_pairs; + max_pairs; + no_sparse; + keys; + values; + ignore_empty; +} + +let rec default_field_options + ?rules:((rules:field_rules option) = None) + () : field_options = { + rules; +} + +type message_options_mutable = { + mutable disabled : bool option; + mutable ignored : bool option; +} + +let default_message_options_mutable () : message_options_mutable = { + disabled = None; + ignored = None; +} + +type oneof_options_mutable = { + mutable required : bool option; +} + +let default_oneof_options_mutable () : oneof_options_mutable = { + required = None; +} + +type message_rules_mutable = { + mutable skip : bool option; + mutable required : bool option; +} + +let default_message_rules_mutable () : message_rules_mutable = { + skip = None; + required = None; +} + +type float_rules_mutable = { + mutable const : float option; + mutable lt : float option; + mutable lte : float option; + mutable gt : float option; + mutable gte : float option; + mutable in_ : float list; + mutable not_in : float list; + mutable ignore_empty : bool option; +} + +let default_float_rules_mutable () : float_rules_mutable = { + const = None; + lt = None; + lte = None; + gt = None; + gte = None; + in_ = []; + not_in = []; + ignore_empty = None; +} + +type double_rules_mutable = { + mutable const : float option; + mutable lt : float option; + mutable lte : float option; + mutable gt : float option; + mutable gte : float option; + mutable in_ : float list; + mutable not_in : float list; + mutable ignore_empty : bool option; +} + +let default_double_rules_mutable () : double_rules_mutable = { + const = None; + lt = None; + lte = None; + gt = None; + gte = None; + in_ = []; + not_in = []; + ignore_empty = None; +} + +type int32_rules_mutable = { + mutable const : int32 option; + mutable lt : int32 option; + mutable lte : int32 option; + mutable gt : int32 option; + mutable gte : int32 option; + mutable in_ : int32 list; + mutable not_in : int32 list; + mutable ignore_empty : bool option; +} + +let default_int32_rules_mutable () : int32_rules_mutable = { + const = None; + lt = None; + lte = None; + gt = None; + gte = None; + in_ = []; + not_in = []; + ignore_empty = None; +} + +type int64_rules_mutable = { + mutable const : int64 option; + mutable lt : int64 option; + mutable lte : int64 option; + mutable gt : int64 option; + mutable gte : int64 option; + mutable in_ : int64 list; + mutable not_in : int64 list; + mutable ignore_empty : bool option; +} + +let default_int64_rules_mutable () : int64_rules_mutable = { + const = None; + lt = None; + lte = None; + gt = None; + gte = None; + in_ = []; + not_in = []; + ignore_empty = None; +} + +type uint32_rules_mutable = { + mutable const : int32 option; + mutable lt : int32 option; + mutable lte : int32 option; + mutable gt : int32 option; + mutable gte : int32 option; + mutable in_ : int32 list; + mutable not_in : int32 list; + mutable ignore_empty : bool option; +} + +let default_uint32_rules_mutable () : uint32_rules_mutable = { + const = None; + lt = None; + lte = None; + gt = None; + gte = None; + in_ = []; + not_in = []; + ignore_empty = None; +} + +type uint64_rules_mutable = { + mutable const : int64 option; + mutable lt : int64 option; + mutable lte : int64 option; + mutable gt : int64 option; + mutable gte : int64 option; + mutable in_ : int64 list; + mutable not_in : int64 list; + mutable ignore_empty : bool option; +} + +let default_uint64_rules_mutable () : uint64_rules_mutable = { + const = None; + lt = None; + lte = None; + gt = None; + gte = None; + in_ = []; + not_in = []; + ignore_empty = None; +} + +type sint32_rules_mutable = { + mutable const : int32 option; + mutable lt : int32 option; + mutable lte : int32 option; + mutable gt : int32 option; + mutable gte : int32 option; + mutable in_ : int32 list; + mutable not_in : int32 list; + mutable ignore_empty : bool option; +} + +let default_sint32_rules_mutable () : sint32_rules_mutable = { + const = None; + lt = None; + lte = None; + gt = None; + gte = None; + in_ = []; + not_in = []; + ignore_empty = None; +} + +type sint64_rules_mutable = { + mutable const : int64 option; + mutable lt : int64 option; + mutable lte : int64 option; + mutable gt : int64 option; + mutable gte : int64 option; + mutable in_ : int64 list; + mutable not_in : int64 list; + mutable ignore_empty : bool option; +} + +let default_sint64_rules_mutable () : sint64_rules_mutable = { + const = None; + lt = None; + lte = None; + gt = None; + gte = None; + in_ = []; + not_in = []; + ignore_empty = None; +} + +type fixed32_rules_mutable = { + mutable const : int32 option; + mutable lt : int32 option; + mutable lte : int32 option; + mutable gt : int32 option; + mutable gte : int32 option; + mutable in_ : int32 list; + mutable not_in : int32 list; + mutable ignore_empty : bool option; +} + +let default_fixed32_rules_mutable () : fixed32_rules_mutable = { + const = None; + lt = None; + lte = None; + gt = None; + gte = None; + in_ = []; + not_in = []; + ignore_empty = None; +} + +type fixed64_rules_mutable = { + mutable const : int64 option; + mutable lt : int64 option; + mutable lte : int64 option; + mutable gt : int64 option; + mutable gte : int64 option; + mutable in_ : int64 list; + mutable not_in : int64 list; + mutable ignore_empty : bool option; +} + +let default_fixed64_rules_mutable () : fixed64_rules_mutable = { + const = None; + lt = None; + lte = None; + gt = None; + gte = None; + in_ = []; + not_in = []; + ignore_empty = None; +} + +type sfixed32_rules_mutable = { + mutable const : int32 option; + mutable lt : int32 option; + mutable lte : int32 option; + mutable gt : int32 option; + mutable gte : int32 option; + mutable in_ : int32 list; + mutable not_in : int32 list; + mutable ignore_empty : bool option; +} + +let default_sfixed32_rules_mutable () : sfixed32_rules_mutable = { + const = None; + lt = None; + lte = None; + gt = None; + gte = None; + in_ = []; + not_in = []; + ignore_empty = None; +} + +type sfixed64_rules_mutable = { + mutable const : int64 option; + mutable lt : int64 option; + mutable lte : int64 option; + mutable gt : int64 option; + mutable gte : int64 option; + mutable in_ : int64 list; + mutable not_in : int64 list; + mutable ignore_empty : bool option; +} + +let default_sfixed64_rules_mutable () : sfixed64_rules_mutable = { + const = None; + lt = None; + lte = None; + gt = None; + gte = None; + in_ = []; + not_in = []; + ignore_empty = None; +} + +type bool_rules_mutable = { + mutable const : bool option; +} + +let default_bool_rules_mutable () : bool_rules_mutable = { + const = None; +} + +type string_rules_mutable = { + mutable const : string option; + mutable len : int64 option; + mutable min_len : int64 option; + mutable max_len : int64 option; + mutable len_bytes : int64 option; + mutable min_bytes : int64 option; + mutable max_bytes : int64 option; + mutable pattern : string option; + mutable prefix : string option; + mutable suffix : string option; + mutable contains : string option; + mutable not_contains : string option; + mutable in_ : string list; + mutable not_in : string list; + mutable well_known : string_rules_well_known option; + mutable strict : bool option; + mutable ignore_empty : bool option; +} + +let default_string_rules_mutable () : string_rules_mutable = { + const = None; + len = None; + min_len = None; + max_len = None; + len_bytes = None; + min_bytes = None; + max_bytes = None; + pattern = None; + prefix = None; + suffix = None; + contains = None; + not_contains = None; + in_ = []; + not_in = []; + well_known = None; + strict = Some (true); + ignore_empty = None; +} + +type bytes_rules_mutable = { + mutable const : bytes option; + mutable len : int64 option; + mutable min_len : int64 option; + mutable max_len : int64 option; + mutable pattern : string option; + mutable prefix : bytes option; + mutable suffix : bytes option; + mutable contains : bytes option; + mutable in_ : bytes list; + mutable not_in : bytes list; + mutable well_known : bytes_rules_well_known option; + mutable ignore_empty : bool option; +} + +let default_bytes_rules_mutable () : bytes_rules_mutable = { + const = None; + len = None; + min_len = None; + max_len = None; + pattern = None; + prefix = None; + suffix = None; + contains = None; + in_ = []; + not_in = []; + well_known = None; + ignore_empty = None; +} + +type enum_rules_mutable = { + mutable const : int32 option; + mutable defined_only : bool option; + mutable in_ : int32 list; + mutable not_in : int32 list; +} + +let default_enum_rules_mutable () : enum_rules_mutable = { + const = None; + defined_only = None; + in_ = []; + not_in = []; +} + +type any_rules_mutable = { + mutable required : bool option; + mutable in_ : string list; + mutable not_in : string list; +} + +let default_any_rules_mutable () : any_rules_mutable = { + required = None; + in_ = []; + not_in = []; +} + +type field_rules_mutable = { + mutable message : message_rules option; + mutable type_ : field_rules_type option; +} + +let default_field_rules_mutable () : field_rules_mutable = { + message = None; + type_ = None; +} + +type repeated_rules_mutable = { + mutable min_items : int64 option; + mutable max_items : int64 option; + mutable unique : bool option; + mutable items : field_rules option; + mutable ignore_empty : bool option; +} + +let default_repeated_rules_mutable () : repeated_rules_mutable = { + min_items = None; + max_items = None; + unique = None; + items = None; + ignore_empty = None; +} + +type map_rules_mutable = { + mutable min_pairs : int64 option; + mutable max_pairs : int64 option; + mutable no_sparse : bool option; + mutable keys : field_rules option; + mutable values : field_rules option; + mutable ignore_empty : bool option; +} + +let default_map_rules_mutable () : map_rules_mutable = { + min_pairs = None; + max_pairs = None; + no_sparse = None; + keys = None; + values = None; + ignore_empty = None; +} + +type field_options_mutable = { + mutable rules : field_rules option; +} + +let default_field_options_mutable () : field_options_mutable = { + rules = None; +} + +[@@@ocaml.warning "-27-30-39"] + +(** {2 Pb_option.set Decoding} *) + +let rec decode_pb_options_message_options d = + let v = default_message_options_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("disabled", pb_options_value) -> + v.disabled <- Some (Pbrt_pb_options.bool pb_options_value "message_options" "disabled") + | ("ignored", pb_options_value) -> + v.ignored <- Some (Pbrt_pb_options.bool pb_options_value "message_options" "ignored") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + disabled = v.disabled; + ignored = v.ignored; + } : message_options) + +let rec decode_pb_options_oneof_options d = + let v = default_oneof_options_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("required", pb_options_value) -> + v.required <- Some (Pbrt_pb_options.bool pb_options_value "oneof_options" "required") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + required = v.required; + } : oneof_options) + +let rec decode_pb_options_message_rules d = + let v = default_message_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("skip", pb_options_value) -> + v.skip <- Some (Pbrt_pb_options.bool pb_options_value "message_rules" "skip") + | ("required", pb_options_value) -> + v.required <- Some (Pbrt_pb_options.bool pb_options_value "message_rules" "required") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + skip = v.skip; + required = v.required; + } : message_rules) + +let rec decode_pb_options_float_rules d = + let v = default_float_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("const", pb_options_value) -> + v.const <- Some (Pbrt_pb_options.float pb_options_value "float_rules" "const") + | ("lt", pb_options_value) -> + v.lt <- Some (Pbrt_pb_options.float pb_options_value "float_rules" "lt") + | ("lte", pb_options_value) -> + v.lte <- Some (Pbrt_pb_options.float pb_options_value "float_rules" "lte") + | ("gt", pb_options_value) -> + v.gt <- Some (Pbrt_pb_options.float pb_options_value "float_rules" "gt") + | ("gte", pb_options_value) -> + v.gte <- Some (Pbrt_pb_options.float pb_options_value "float_rules" "gte") + | ("in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.in_ <- List.map (function + | pb_options_value -> Pbrt_pb_options.float pb_options_value "float_rules" "in_" + ) l; + end + | ("not_in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.not_in <- List.map (function + | pb_options_value -> Pbrt_pb_options.float pb_options_value "float_rules" "not_in" + ) l; + end + | ("ignore_empty", pb_options_value) -> + v.ignore_empty <- Some (Pbrt_pb_options.bool pb_options_value "float_rules" "ignore_empty") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + const = v.const; + lt = v.lt; + lte = v.lte; + gt = v.gt; + gte = v.gte; + in_ = v.in_; + not_in = v.not_in; + ignore_empty = v.ignore_empty; + } : float_rules) + +let rec decode_pb_options_double_rules d = + let v = default_double_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("const", pb_options_value) -> + v.const <- Some (Pbrt_pb_options.float pb_options_value "double_rules" "const") + | ("lt", pb_options_value) -> + v.lt <- Some (Pbrt_pb_options.float pb_options_value "double_rules" "lt") + | ("lte", pb_options_value) -> + v.lte <- Some (Pbrt_pb_options.float pb_options_value "double_rules" "lte") + | ("gt", pb_options_value) -> + v.gt <- Some (Pbrt_pb_options.float pb_options_value "double_rules" "gt") + | ("gte", pb_options_value) -> + v.gte <- Some (Pbrt_pb_options.float pb_options_value "double_rules" "gte") + | ("in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.in_ <- List.map (function + | pb_options_value -> Pbrt_pb_options.float pb_options_value "double_rules" "in_" + ) l; + end + | ("not_in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.not_in <- List.map (function + | pb_options_value -> Pbrt_pb_options.float pb_options_value "double_rules" "not_in" + ) l; + end + | ("ignore_empty", pb_options_value) -> + v.ignore_empty <- Some (Pbrt_pb_options.bool pb_options_value "double_rules" "ignore_empty") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + const = v.const; + lt = v.lt; + lte = v.lte; + gt = v.gt; + gte = v.gte; + in_ = v.in_; + not_in = v.not_in; + ignore_empty = v.ignore_empty; + } : double_rules) + +let rec decode_pb_options_int32_rules d = + let v = default_int32_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("const", pb_options_value) -> + v.const <- Some (Pbrt_pb_options.int32 pb_options_value "int32_rules" "const") + | ("lt", pb_options_value) -> + v.lt <- Some (Pbrt_pb_options.int32 pb_options_value "int32_rules" "lt") + | ("lte", pb_options_value) -> + v.lte <- Some (Pbrt_pb_options.int32 pb_options_value "int32_rules" "lte") + | ("gt", pb_options_value) -> + v.gt <- Some (Pbrt_pb_options.int32 pb_options_value "int32_rules" "gt") + | ("gte", pb_options_value) -> + v.gte <- Some (Pbrt_pb_options.int32 pb_options_value "int32_rules" "gte") + | ("in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.in_ <- List.map (function + | pb_options_value -> Pbrt_pb_options.int32 pb_options_value "int32_rules" "in_" + ) l; + end + | ("not_in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.not_in <- List.map (function + | pb_options_value -> Pbrt_pb_options.int32 pb_options_value "int32_rules" "not_in" + ) l; + end + | ("ignore_empty", pb_options_value) -> + v.ignore_empty <- Some (Pbrt_pb_options.bool pb_options_value "int32_rules" "ignore_empty") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + const = v.const; + lt = v.lt; + lte = v.lte; + gt = v.gt; + gte = v.gte; + in_ = v.in_; + not_in = v.not_in; + ignore_empty = v.ignore_empty; + } : int32_rules) + +let rec decode_pb_options_int64_rules d = + let v = default_int64_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("const", pb_options_value) -> + v.const <- Some (Pbrt_pb_options.int64 pb_options_value "int64_rules" "const") + | ("lt", pb_options_value) -> + v.lt <- Some (Pbrt_pb_options.int64 pb_options_value "int64_rules" "lt") + | ("lte", pb_options_value) -> + v.lte <- Some (Pbrt_pb_options.int64 pb_options_value "int64_rules" "lte") + | ("gt", pb_options_value) -> + v.gt <- Some (Pbrt_pb_options.int64 pb_options_value "int64_rules" "gt") + | ("gte", pb_options_value) -> + v.gte <- Some (Pbrt_pb_options.int64 pb_options_value "int64_rules" "gte") + | ("in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.in_ <- List.map (function + | pb_options_value -> Pbrt_pb_options.int64 pb_options_value "int64_rules" "in_" + ) l; + end + | ("not_in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.not_in <- List.map (function + | pb_options_value -> Pbrt_pb_options.int64 pb_options_value "int64_rules" "not_in" + ) l; + end + | ("ignore_empty", pb_options_value) -> + v.ignore_empty <- Some (Pbrt_pb_options.bool pb_options_value "int64_rules" "ignore_empty") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + const = v.const; + lt = v.lt; + lte = v.lte; + gt = v.gt; + gte = v.gte; + in_ = v.in_; + not_in = v.not_in; + ignore_empty = v.ignore_empty; + } : int64_rules) + +let rec decode_pb_options_uint32_rules d = + let v = default_uint32_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("const", pb_options_value) -> + v.const <- Some (Pbrt_pb_options.int32 pb_options_value "uint32_rules" "const") + | ("lt", pb_options_value) -> + v.lt <- Some (Pbrt_pb_options.int32 pb_options_value "uint32_rules" "lt") + | ("lte", pb_options_value) -> + v.lte <- Some (Pbrt_pb_options.int32 pb_options_value "uint32_rules" "lte") + | ("gt", pb_options_value) -> + v.gt <- Some (Pbrt_pb_options.int32 pb_options_value "uint32_rules" "gt") + | ("gte", pb_options_value) -> + v.gte <- Some (Pbrt_pb_options.int32 pb_options_value "uint32_rules" "gte") + | ("in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.in_ <- List.map (function + | pb_options_value -> Pbrt_pb_options.int32 pb_options_value "uint32_rules" "in_" + ) l; + end + | ("not_in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.not_in <- List.map (function + | pb_options_value -> Pbrt_pb_options.int32 pb_options_value "uint32_rules" "not_in" + ) l; + end + | ("ignore_empty", pb_options_value) -> + v.ignore_empty <- Some (Pbrt_pb_options.bool pb_options_value "uint32_rules" "ignore_empty") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + const = v.const; + lt = v.lt; + lte = v.lte; + gt = v.gt; + gte = v.gte; + in_ = v.in_; + not_in = v.not_in; + ignore_empty = v.ignore_empty; + } : uint32_rules) + +let rec decode_pb_options_uint64_rules d = + let v = default_uint64_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("const", pb_options_value) -> + v.const <- Some (Pbrt_pb_options.int64 pb_options_value "uint64_rules" "const") + | ("lt", pb_options_value) -> + v.lt <- Some (Pbrt_pb_options.int64 pb_options_value "uint64_rules" "lt") + | ("lte", pb_options_value) -> + v.lte <- Some (Pbrt_pb_options.int64 pb_options_value "uint64_rules" "lte") + | ("gt", pb_options_value) -> + v.gt <- Some (Pbrt_pb_options.int64 pb_options_value "uint64_rules" "gt") + | ("gte", pb_options_value) -> + v.gte <- Some (Pbrt_pb_options.int64 pb_options_value "uint64_rules" "gte") + | ("in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.in_ <- List.map (function + | pb_options_value -> Pbrt_pb_options.int64 pb_options_value "uint64_rules" "in_" + ) l; + end + | ("not_in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.not_in <- List.map (function + | pb_options_value -> Pbrt_pb_options.int64 pb_options_value "uint64_rules" "not_in" + ) l; + end + | ("ignore_empty", pb_options_value) -> + v.ignore_empty <- Some (Pbrt_pb_options.bool pb_options_value "uint64_rules" "ignore_empty") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + const = v.const; + lt = v.lt; + lte = v.lte; + gt = v.gt; + gte = v.gte; + in_ = v.in_; + not_in = v.not_in; + ignore_empty = v.ignore_empty; + } : uint64_rules) + +let rec decode_pb_options_sint32_rules d = + let v = default_sint32_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("const", pb_options_value) -> + v.const <- Some (Pbrt_pb_options.int32 pb_options_value "sint32_rules" "const") + | ("lt", pb_options_value) -> + v.lt <- Some (Pbrt_pb_options.int32 pb_options_value "sint32_rules" "lt") + | ("lte", pb_options_value) -> + v.lte <- Some (Pbrt_pb_options.int32 pb_options_value "sint32_rules" "lte") + | ("gt", pb_options_value) -> + v.gt <- Some (Pbrt_pb_options.int32 pb_options_value "sint32_rules" "gt") + | ("gte", pb_options_value) -> + v.gte <- Some (Pbrt_pb_options.int32 pb_options_value "sint32_rules" "gte") + | ("in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.in_ <- List.map (function + | pb_options_value -> Pbrt_pb_options.int32 pb_options_value "sint32_rules" "in_" + ) l; + end + | ("not_in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.not_in <- List.map (function + | pb_options_value -> Pbrt_pb_options.int32 pb_options_value "sint32_rules" "not_in" + ) l; + end + | ("ignore_empty", pb_options_value) -> + v.ignore_empty <- Some (Pbrt_pb_options.bool pb_options_value "sint32_rules" "ignore_empty") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + const = v.const; + lt = v.lt; + lte = v.lte; + gt = v.gt; + gte = v.gte; + in_ = v.in_; + not_in = v.not_in; + ignore_empty = v.ignore_empty; + } : sint32_rules) + +let rec decode_pb_options_sint64_rules d = + let v = default_sint64_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("const", pb_options_value) -> + v.const <- Some (Pbrt_pb_options.int64 pb_options_value "sint64_rules" "const") + | ("lt", pb_options_value) -> + v.lt <- Some (Pbrt_pb_options.int64 pb_options_value "sint64_rules" "lt") + | ("lte", pb_options_value) -> + v.lte <- Some (Pbrt_pb_options.int64 pb_options_value "sint64_rules" "lte") + | ("gt", pb_options_value) -> + v.gt <- Some (Pbrt_pb_options.int64 pb_options_value "sint64_rules" "gt") + | ("gte", pb_options_value) -> + v.gte <- Some (Pbrt_pb_options.int64 pb_options_value "sint64_rules" "gte") + | ("in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.in_ <- List.map (function + | pb_options_value -> Pbrt_pb_options.int64 pb_options_value "sint64_rules" "in_" + ) l; + end + | ("not_in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.not_in <- List.map (function + | pb_options_value -> Pbrt_pb_options.int64 pb_options_value "sint64_rules" "not_in" + ) l; + end + | ("ignore_empty", pb_options_value) -> + v.ignore_empty <- Some (Pbrt_pb_options.bool pb_options_value "sint64_rules" "ignore_empty") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + const = v.const; + lt = v.lt; + lte = v.lte; + gt = v.gt; + gte = v.gte; + in_ = v.in_; + not_in = v.not_in; + ignore_empty = v.ignore_empty; + } : sint64_rules) + +let rec decode_pb_options_fixed32_rules d = + let v = default_fixed32_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("const", pb_options_value) -> + v.const <- Some (Pbrt_pb_options.int32 pb_options_value "fixed32_rules" "const") + | ("lt", pb_options_value) -> + v.lt <- Some (Pbrt_pb_options.int32 pb_options_value "fixed32_rules" "lt") + | ("lte", pb_options_value) -> + v.lte <- Some (Pbrt_pb_options.int32 pb_options_value "fixed32_rules" "lte") + | ("gt", pb_options_value) -> + v.gt <- Some (Pbrt_pb_options.int32 pb_options_value "fixed32_rules" "gt") + | ("gte", pb_options_value) -> + v.gte <- Some (Pbrt_pb_options.int32 pb_options_value "fixed32_rules" "gte") + | ("in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.in_ <- List.map (function + | pb_options_value -> Pbrt_pb_options.int32 pb_options_value "fixed32_rules" "in_" + ) l; + end + | ("not_in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.not_in <- List.map (function + | pb_options_value -> Pbrt_pb_options.int32 pb_options_value "fixed32_rules" "not_in" + ) l; + end + | ("ignore_empty", pb_options_value) -> + v.ignore_empty <- Some (Pbrt_pb_options.bool pb_options_value "fixed32_rules" "ignore_empty") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + const = v.const; + lt = v.lt; + lte = v.lte; + gt = v.gt; + gte = v.gte; + in_ = v.in_; + not_in = v.not_in; + ignore_empty = v.ignore_empty; + } : fixed32_rules) + +let rec decode_pb_options_fixed64_rules d = + let v = default_fixed64_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("const", pb_options_value) -> + v.const <- Some (Pbrt_pb_options.int64 pb_options_value "fixed64_rules" "const") + | ("lt", pb_options_value) -> + v.lt <- Some (Pbrt_pb_options.int64 pb_options_value "fixed64_rules" "lt") + | ("lte", pb_options_value) -> + v.lte <- Some (Pbrt_pb_options.int64 pb_options_value "fixed64_rules" "lte") + | ("gt", pb_options_value) -> + v.gt <- Some (Pbrt_pb_options.int64 pb_options_value "fixed64_rules" "gt") + | ("gte", pb_options_value) -> + v.gte <- Some (Pbrt_pb_options.int64 pb_options_value "fixed64_rules" "gte") + | ("in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.in_ <- List.map (function + | pb_options_value -> Pbrt_pb_options.int64 pb_options_value "fixed64_rules" "in_" + ) l; + end + | ("not_in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.not_in <- List.map (function + | pb_options_value -> Pbrt_pb_options.int64 pb_options_value "fixed64_rules" "not_in" + ) l; + end + | ("ignore_empty", pb_options_value) -> + v.ignore_empty <- Some (Pbrt_pb_options.bool pb_options_value "fixed64_rules" "ignore_empty") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + const = v.const; + lt = v.lt; + lte = v.lte; + gt = v.gt; + gte = v.gte; + in_ = v.in_; + not_in = v.not_in; + ignore_empty = v.ignore_empty; + } : fixed64_rules) + +let rec decode_pb_options_sfixed32_rules d = + let v = default_sfixed32_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("const", pb_options_value) -> + v.const <- Some (Pbrt_pb_options.int32 pb_options_value "sfixed32_rules" "const") + | ("lt", pb_options_value) -> + v.lt <- Some (Pbrt_pb_options.int32 pb_options_value "sfixed32_rules" "lt") + | ("lte", pb_options_value) -> + v.lte <- Some (Pbrt_pb_options.int32 pb_options_value "sfixed32_rules" "lte") + | ("gt", pb_options_value) -> + v.gt <- Some (Pbrt_pb_options.int32 pb_options_value "sfixed32_rules" "gt") + | ("gte", pb_options_value) -> + v.gte <- Some (Pbrt_pb_options.int32 pb_options_value "sfixed32_rules" "gte") + | ("in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.in_ <- List.map (function + | pb_options_value -> Pbrt_pb_options.int32 pb_options_value "sfixed32_rules" "in_" + ) l; + end + | ("not_in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.not_in <- List.map (function + | pb_options_value -> Pbrt_pb_options.int32 pb_options_value "sfixed32_rules" "not_in" + ) l; + end + | ("ignore_empty", pb_options_value) -> + v.ignore_empty <- Some (Pbrt_pb_options.bool pb_options_value "sfixed32_rules" "ignore_empty") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + const = v.const; + lt = v.lt; + lte = v.lte; + gt = v.gt; + gte = v.gte; + in_ = v.in_; + not_in = v.not_in; + ignore_empty = v.ignore_empty; + } : sfixed32_rules) + +let rec decode_pb_options_sfixed64_rules d = + let v = default_sfixed64_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("const", pb_options_value) -> + v.const <- Some (Pbrt_pb_options.int64 pb_options_value "sfixed64_rules" "const") + | ("lt", pb_options_value) -> + v.lt <- Some (Pbrt_pb_options.int64 pb_options_value "sfixed64_rules" "lt") + | ("lte", pb_options_value) -> + v.lte <- Some (Pbrt_pb_options.int64 pb_options_value "sfixed64_rules" "lte") + | ("gt", pb_options_value) -> + v.gt <- Some (Pbrt_pb_options.int64 pb_options_value "sfixed64_rules" "gt") + | ("gte", pb_options_value) -> + v.gte <- Some (Pbrt_pb_options.int64 pb_options_value "sfixed64_rules" "gte") + | ("in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.in_ <- List.map (function + | pb_options_value -> Pbrt_pb_options.int64 pb_options_value "sfixed64_rules" "in_" + ) l; + end + | ("not_in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.not_in <- List.map (function + | pb_options_value -> Pbrt_pb_options.int64 pb_options_value "sfixed64_rules" "not_in" + ) l; + end + | ("ignore_empty", pb_options_value) -> + v.ignore_empty <- Some (Pbrt_pb_options.bool pb_options_value "sfixed64_rules" "ignore_empty") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + const = v.const; + lt = v.lt; + lte = v.lte; + gt = v.gt; + gte = v.gte; + in_ = v.in_; + not_in = v.not_in; + ignore_empty = v.ignore_empty; + } : sfixed64_rules) + +let rec decode_pb_options_bool_rules d = + let v = default_bool_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("const", pb_options_value) -> + v.const <- Some (Pbrt_pb_options.bool pb_options_value "bool_rules" "const") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + const = v.const; + } : bool_rules) + +let rec decode_pb_options_known_regex pb_options = + match pb_options with + | Ocaml_protoc_compiler_lib.Pb_option.Scalar_value (Constant_literal "UNKNOWN") -> (Unknown : known_regex) + | Ocaml_protoc_compiler_lib.Pb_option.Scalar_value (Constant_literal "HTTP_HEADER_NAME") -> (Http_header_name : known_regex) + | Ocaml_protoc_compiler_lib.Pb_option.Scalar_value (Constant_literal "HTTP_HEADER_VALUE") -> (Http_header_value : known_regex) + | _ -> Pbrt_pb_options.E.malformed_variant "known_regex" + +let rec decode_pb_options_string_rules_well_known pb_options = + let assoc = match pb_options with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + let rec loop = function + | [] -> Pbrt_pb_options.E.malformed_variant "string_rules_well_known" + | ("email", pb_options_value)::_ -> + (Email (Pbrt_pb_options.bool pb_options_value "string_rules_well_known" "Email") : string_rules_well_known) + | ("hostname", pb_options_value)::_ -> + (Hostname (Pbrt_pb_options.bool pb_options_value "string_rules_well_known" "Hostname") : string_rules_well_known) + | ("ip", pb_options_value)::_ -> + (Ip (Pbrt_pb_options.bool pb_options_value "string_rules_well_known" "Ip") : string_rules_well_known) + | ("ipv4", pb_options_value)::_ -> + (Ipv4 (Pbrt_pb_options.bool pb_options_value "string_rules_well_known" "Ipv4") : string_rules_well_known) + | ("ipv6", pb_options_value)::_ -> + (Ipv6 (Pbrt_pb_options.bool pb_options_value "string_rules_well_known" "Ipv6") : string_rules_well_known) + | ("uri", pb_options_value)::_ -> + (Uri (Pbrt_pb_options.bool pb_options_value "string_rules_well_known" "Uri") : string_rules_well_known) + | ("uriRef", pb_options_value)::_ -> + (Uri_ref (Pbrt_pb_options.bool pb_options_value "string_rules_well_known" "Uri_ref") : string_rules_well_known) + | ("address", pb_options_value)::_ -> + (Address (Pbrt_pb_options.bool pb_options_value "string_rules_well_known" "Address") : string_rules_well_known) + | ("uuid", pb_options_value)::_ -> + (Uuid (Pbrt_pb_options.bool pb_options_value "string_rules_well_known" "Uuid") : string_rules_well_known) + | ("wellKnownRegex", pb_options_value)::_ -> + (Well_known_regex ((decode_pb_options_known_regex pb_options_value)) : string_rules_well_known) + + | _ :: tl -> loop tl + in + loop assoc + +and decode_pb_options_string_rules d = + let v = default_string_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("const", pb_options_value) -> + v.const <- Some (Pbrt_pb_options.string pb_options_value "string_rules" "const") + | ("len", pb_options_value) -> + v.len <- Some (Pbrt_pb_options.int64 pb_options_value "string_rules" "len") + | ("min_len", pb_options_value) -> + v.min_len <- Some (Pbrt_pb_options.int64 pb_options_value "string_rules" "min_len") + | ("max_len", pb_options_value) -> + v.max_len <- Some (Pbrt_pb_options.int64 pb_options_value "string_rules" "max_len") + | ("len_bytes", pb_options_value) -> + v.len_bytes <- Some (Pbrt_pb_options.int64 pb_options_value "string_rules" "len_bytes") + | ("min_bytes", pb_options_value) -> + v.min_bytes <- Some (Pbrt_pb_options.int64 pb_options_value "string_rules" "min_bytes") + | ("max_bytes", pb_options_value) -> + v.max_bytes <- Some (Pbrt_pb_options.int64 pb_options_value "string_rules" "max_bytes") + | ("pattern", pb_options_value) -> + v.pattern <- Some (Pbrt_pb_options.string pb_options_value "string_rules" "pattern") + | ("prefix", pb_options_value) -> + v.prefix <- Some (Pbrt_pb_options.string pb_options_value "string_rules" "prefix") + | ("suffix", pb_options_value) -> + v.suffix <- Some (Pbrt_pb_options.string pb_options_value "string_rules" "suffix") + | ("contains", pb_options_value) -> + v.contains <- Some (Pbrt_pb_options.string pb_options_value "string_rules" "contains") + | ("not_contains", pb_options_value) -> + v.not_contains <- Some (Pbrt_pb_options.string pb_options_value "string_rules" "not_contains") + | ("in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.in_ <- List.map (function + | pb_options_value -> Pbrt_pb_options.string pb_options_value "string_rules" "in_" + ) l; + end + | ("not_in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.not_in <- List.map (function + | pb_options_value -> Pbrt_pb_options.string pb_options_value "string_rules" "not_in" + ) l; + end + | ("email", pb_options_value) -> + v.well_known <- Some (Email (Pbrt_pb_options.bool pb_options_value "string_rules" "well_known")) + | ("hostname", pb_options_value) -> + v.well_known <- Some (Hostname (Pbrt_pb_options.bool pb_options_value "string_rules" "well_known")) + | ("ip", pb_options_value) -> + v.well_known <- Some (Ip (Pbrt_pb_options.bool pb_options_value "string_rules" "well_known")) + | ("ipv4", pb_options_value) -> + v.well_known <- Some (Ipv4 (Pbrt_pb_options.bool pb_options_value "string_rules" "well_known")) + | ("ipv6", pb_options_value) -> + v.well_known <- Some (Ipv6 (Pbrt_pb_options.bool pb_options_value "string_rules" "well_known")) + | ("uri", pb_options_value) -> + v.well_known <- Some (Uri (Pbrt_pb_options.bool pb_options_value "string_rules" "well_known")) + | ("uriRef", pb_options_value) -> + v.well_known <- Some (Uri_ref (Pbrt_pb_options.bool pb_options_value "string_rules" "well_known")) + | ("address", pb_options_value) -> + v.well_known <- Some (Address (Pbrt_pb_options.bool pb_options_value "string_rules" "well_known")) + | ("uuid", pb_options_value) -> + v.well_known <- Some (Uuid (Pbrt_pb_options.bool pb_options_value "string_rules" "well_known")) + | ("wellKnownRegex", pb_options_value) -> + v.well_known <- Some (Well_known_regex ((decode_pb_options_known_regex pb_options_value))) + | ("strict", pb_options_value) -> + v.strict <- Some (Pbrt_pb_options.bool pb_options_value "string_rules" "strict") + | ("ignore_empty", pb_options_value) -> + v.ignore_empty <- Some (Pbrt_pb_options.bool pb_options_value "string_rules" "ignore_empty") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + const = v.const; + len = v.len; + min_len = v.min_len; + max_len = v.max_len; + len_bytes = v.len_bytes; + min_bytes = v.min_bytes; + max_bytes = v.max_bytes; + pattern = v.pattern; + prefix = v.prefix; + suffix = v.suffix; + contains = v.contains; + not_contains = v.not_contains; + in_ = v.in_; + not_in = v.not_in; + well_known = v.well_known; + strict = v.strict; + ignore_empty = v.ignore_empty; + } : string_rules) + +let rec decode_pb_options_bytes_rules_well_known pb_options = + let assoc = match pb_options with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + let rec loop = function + | [] -> Pbrt_pb_options.E.malformed_variant "bytes_rules_well_known" + | ("ip", pb_options_value)::_ -> + (Ip (Pbrt_pb_options.bool pb_options_value "bytes_rules_well_known" "Ip") : bytes_rules_well_known) + | ("ipv4", pb_options_value)::_ -> + (Ipv4 (Pbrt_pb_options.bool pb_options_value "bytes_rules_well_known" "Ipv4") : bytes_rules_well_known) + | ("ipv6", pb_options_value)::_ -> + (Ipv6 (Pbrt_pb_options.bool pb_options_value "bytes_rules_well_known" "Ipv6") : bytes_rules_well_known) + + | _ :: tl -> loop tl + in + loop assoc + +and decode_pb_options_bytes_rules d = + let v = default_bytes_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("const", pb_options_value) -> + v.const <- Some (Pbrt_pb_options.bytes pb_options_value "bytes_rules" "const") + | ("len", pb_options_value) -> + v.len <- Some (Pbrt_pb_options.int64 pb_options_value "bytes_rules" "len") + | ("min_len", pb_options_value) -> + v.min_len <- Some (Pbrt_pb_options.int64 pb_options_value "bytes_rules" "min_len") + | ("max_len", pb_options_value) -> + v.max_len <- Some (Pbrt_pb_options.int64 pb_options_value "bytes_rules" "max_len") + | ("pattern", pb_options_value) -> + v.pattern <- Some (Pbrt_pb_options.string pb_options_value "bytes_rules" "pattern") + | ("prefix", pb_options_value) -> + v.prefix <- Some (Pbrt_pb_options.bytes pb_options_value "bytes_rules" "prefix") + | ("suffix", pb_options_value) -> + v.suffix <- Some (Pbrt_pb_options.bytes pb_options_value "bytes_rules" "suffix") + | ("contains", pb_options_value) -> + v.contains <- Some (Pbrt_pb_options.bytes pb_options_value "bytes_rules" "contains") + | ("in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.in_ <- List.map (function + | pb_options_value -> Pbrt_pb_options.bytes pb_options_value "bytes_rules" "in_" + ) l; + end + | ("not_in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.not_in <- List.map (function + | pb_options_value -> Pbrt_pb_options.bytes pb_options_value "bytes_rules" "not_in" + ) l; + end + | ("ip", pb_options_value) -> + v.well_known <- Some (Ip (Pbrt_pb_options.bool pb_options_value "bytes_rules" "well_known")) + | ("ipv4", pb_options_value) -> + v.well_known <- Some (Ipv4 (Pbrt_pb_options.bool pb_options_value "bytes_rules" "well_known")) + | ("ipv6", pb_options_value) -> + v.well_known <- Some (Ipv6 (Pbrt_pb_options.bool pb_options_value "bytes_rules" "well_known")) + | ("ignore_empty", pb_options_value) -> + v.ignore_empty <- Some (Pbrt_pb_options.bool pb_options_value "bytes_rules" "ignore_empty") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + const = v.const; + len = v.len; + min_len = v.min_len; + max_len = v.max_len; + pattern = v.pattern; + prefix = v.prefix; + suffix = v.suffix; + contains = v.contains; + in_ = v.in_; + not_in = v.not_in; + well_known = v.well_known; + ignore_empty = v.ignore_empty; + } : bytes_rules) + +let rec decode_pb_options_enum_rules d = + let v = default_enum_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("const", pb_options_value) -> + v.const <- Some (Pbrt_pb_options.int32 pb_options_value "enum_rules" "const") + | ("defined_only", pb_options_value) -> + v.defined_only <- Some (Pbrt_pb_options.bool pb_options_value "enum_rules" "defined_only") + | ("in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.in_ <- List.map (function + | pb_options_value -> Pbrt_pb_options.int32 pb_options_value "enum_rules" "in_" + ) l; + end + | ("not_in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.not_in <- List.map (function + | pb_options_value -> Pbrt_pb_options.int32 pb_options_value "enum_rules" "not_in" + ) l; + end + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + const = v.const; + defined_only = v.defined_only; + in_ = v.in_; + not_in = v.not_in; + } : enum_rules) + +let rec decode_pb_options_any_rules d = + let v = default_any_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("required", pb_options_value) -> + v.required <- Some (Pbrt_pb_options.bool pb_options_value "any_rules" "required") + | ("in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.in_ <- List.map (function + | pb_options_value -> Pbrt_pb_options.string pb_options_value "any_rules" "in_" + ) l; + end + | ("not_in", Ocaml_protoc_compiler_lib.Pb_option.List_literal l) -> begin + v.not_in <- List.map (function + | pb_options_value -> Pbrt_pb_options.string pb_options_value "any_rules" "not_in" + ) l; + end + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + required = v.required; + in_ = v.in_; + not_in = v.not_in; + } : any_rules) + +let rec decode_pb_options_field_rules_type pb_options = + let assoc = match pb_options with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + let rec loop = function + | [] -> Pbrt_pb_options.E.malformed_variant "field_rules_type" + | ("float", pb_options_value)::_ -> + (Float ((decode_pb_options_float_rules pb_options_value)) : field_rules_type) + | ("double", pb_options_value)::_ -> + (Double ((decode_pb_options_double_rules pb_options_value)) : field_rules_type) + | ("int32", pb_options_value)::_ -> + (Int32 ((decode_pb_options_int32_rules pb_options_value)) : field_rules_type) + | ("int64", pb_options_value)::_ -> + (Int64 ((decode_pb_options_int64_rules pb_options_value)) : field_rules_type) + | ("uint32", pb_options_value)::_ -> + (Uint32 ((decode_pb_options_uint32_rules pb_options_value)) : field_rules_type) + | ("uint64", pb_options_value)::_ -> + (Uint64 ((decode_pb_options_uint64_rules pb_options_value)) : field_rules_type) + | ("sint32", pb_options_value)::_ -> + (Sint32 ((decode_pb_options_sint32_rules pb_options_value)) : field_rules_type) + | ("sint64", pb_options_value)::_ -> + (Sint64 ((decode_pb_options_sint64_rules pb_options_value)) : field_rules_type) + | ("fixed32", pb_options_value)::_ -> + (Fixed32 ((decode_pb_options_fixed32_rules pb_options_value)) : field_rules_type) + | ("fixed64", pb_options_value)::_ -> + (Fixed64 ((decode_pb_options_fixed64_rules pb_options_value)) : field_rules_type) + | ("sfixed32", pb_options_value)::_ -> + (Sfixed32 ((decode_pb_options_sfixed32_rules pb_options_value)) : field_rules_type) + | ("sfixed64", pb_options_value)::_ -> + (Sfixed64 ((decode_pb_options_sfixed64_rules pb_options_value)) : field_rules_type) + | ("bool", pb_options_value)::_ -> + (Bool ((decode_pb_options_bool_rules pb_options_value)) : field_rules_type) + | ("string", pb_options_value)::_ -> + (String ((decode_pb_options_string_rules pb_options_value)) : field_rules_type) + | ("bytes", pb_options_value)::_ -> + (Bytes ((decode_pb_options_bytes_rules pb_options_value)) : field_rules_type) + | ("enum", pb_options_value)::_ -> + (Enum ((decode_pb_options_enum_rules pb_options_value)) : field_rules_type) + | ("repeated", pb_options_value)::_ -> + (Repeated ((decode_pb_options_repeated_rules pb_options_value)) : field_rules_type) + | ("map", pb_options_value)::_ -> + (Map ((decode_pb_options_map_rules pb_options_value)) : field_rules_type) + | ("any", pb_options_value)::_ -> + (Any ((decode_pb_options_any_rules pb_options_value)) : field_rules_type) + + | _ :: tl -> loop tl + in + loop assoc + +and decode_pb_options_field_rules d = + let v = default_field_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("message", pb_options_value) -> + v.message <- Some ((decode_pb_options_message_rules pb_options_value)) + | ("float", pb_options_value) -> + v.type_ <- Some (Float ((decode_pb_options_float_rules pb_options_value))) + | ("double", pb_options_value) -> + v.type_ <- Some (Double ((decode_pb_options_double_rules pb_options_value))) + | ("int32", pb_options_value) -> + v.type_ <- Some (Int32 ((decode_pb_options_int32_rules pb_options_value))) + | ("int64", pb_options_value) -> + v.type_ <- Some (Int64 ((decode_pb_options_int64_rules pb_options_value))) + | ("uint32", pb_options_value) -> + v.type_ <- Some (Uint32 ((decode_pb_options_uint32_rules pb_options_value))) + | ("uint64", pb_options_value) -> + v.type_ <- Some (Uint64 ((decode_pb_options_uint64_rules pb_options_value))) + | ("sint32", pb_options_value) -> + v.type_ <- Some (Sint32 ((decode_pb_options_sint32_rules pb_options_value))) + | ("sint64", pb_options_value) -> + v.type_ <- Some (Sint64 ((decode_pb_options_sint64_rules pb_options_value))) + | ("fixed32", pb_options_value) -> + v.type_ <- Some (Fixed32 ((decode_pb_options_fixed32_rules pb_options_value))) + | ("fixed64", pb_options_value) -> + v.type_ <- Some (Fixed64 ((decode_pb_options_fixed64_rules pb_options_value))) + | ("sfixed32", pb_options_value) -> + v.type_ <- Some (Sfixed32 ((decode_pb_options_sfixed32_rules pb_options_value))) + | ("sfixed64", pb_options_value) -> + v.type_ <- Some (Sfixed64 ((decode_pb_options_sfixed64_rules pb_options_value))) + | ("bool", pb_options_value) -> + v.type_ <- Some (Bool ((decode_pb_options_bool_rules pb_options_value))) + | ("string", pb_options_value) -> + v.type_ <- Some (String ((decode_pb_options_string_rules pb_options_value))) + | ("bytes", pb_options_value) -> + v.type_ <- Some (Bytes ((decode_pb_options_bytes_rules pb_options_value))) + | ("enum", pb_options_value) -> + v.type_ <- Some (Enum ((decode_pb_options_enum_rules pb_options_value))) + | ("repeated", pb_options_value) -> + v.type_ <- Some (Repeated ((decode_pb_options_repeated_rules pb_options_value))) + | ("map", pb_options_value) -> + v.type_ <- Some (Map ((decode_pb_options_map_rules pb_options_value))) + | ("any", pb_options_value) -> + v.type_ <- Some (Any ((decode_pb_options_any_rules pb_options_value))) + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + message = v.message; + type_ = v.type_; + } : field_rules) + +and decode_pb_options_repeated_rules d = + let v = default_repeated_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("min_items", pb_options_value) -> + v.min_items <- Some (Pbrt_pb_options.int64 pb_options_value "repeated_rules" "min_items") + | ("max_items", pb_options_value) -> + v.max_items <- Some (Pbrt_pb_options.int64 pb_options_value "repeated_rules" "max_items") + | ("unique", pb_options_value) -> + v.unique <- Some (Pbrt_pb_options.bool pb_options_value "repeated_rules" "unique") + | ("items", pb_options_value) -> + v.items <- Some ((decode_pb_options_field_rules pb_options_value)) + | ("ignore_empty", pb_options_value) -> + v.ignore_empty <- Some (Pbrt_pb_options.bool pb_options_value "repeated_rules" "ignore_empty") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + min_items = v.min_items; + max_items = v.max_items; + unique = v.unique; + items = v.items; + ignore_empty = v.ignore_empty; + } : repeated_rules) + +and decode_pb_options_map_rules d = + let v = default_map_rules_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("min_pairs", pb_options_value) -> + v.min_pairs <- Some (Pbrt_pb_options.int64 pb_options_value "map_rules" "min_pairs") + | ("max_pairs", pb_options_value) -> + v.max_pairs <- Some (Pbrt_pb_options.int64 pb_options_value "map_rules" "max_pairs") + | ("no_sparse", pb_options_value) -> + v.no_sparse <- Some (Pbrt_pb_options.bool pb_options_value "map_rules" "no_sparse") + | ("keys", pb_options_value) -> + v.keys <- Some ((decode_pb_options_field_rules pb_options_value)) + | ("values", pb_options_value) -> + v.values <- Some ((decode_pb_options_field_rules pb_options_value)) + | ("ignore_empty", pb_options_value) -> + v.ignore_empty <- Some (Pbrt_pb_options.bool pb_options_value "map_rules" "ignore_empty") + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + min_pairs = v.min_pairs; + max_pairs = v.max_pairs; + no_sparse = v.no_sparse; + keys = v.keys; + values = v.values; + ignore_empty = v.ignore_empty; + } : map_rules) + +let rec decode_pb_options_field_options d = + let v = default_field_options_mutable () in + let assoc = match d with + | Ocaml_protoc_compiler_lib.Pb_option.Message_literal assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("rules", pb_options_value) -> + v.rules <- Some ((decode_pb_options_field_rules pb_options_value)) + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + rules = v.rules; + } : field_options) + +[@@@ocaml.warning "-27-30-39"] + +(** {2 Formatters} *) + +let rec pp_message_options fmt (v:message_options) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "disabled" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.disabled; + Pbrt.Pp.pp_record_field ~first:false "ignored" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.ignored; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_oneof_options fmt (v:oneof_options) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "required" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.required; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_message_rules fmt (v:message_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "skip" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.skip; + Pbrt.Pp.pp_record_field ~first:false "required" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.required; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_float_rules fmt (v:float_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "const" (Pbrt.Pp.pp_option Pbrt.Pp.pp_float) fmt v.const; + Pbrt.Pp.pp_record_field ~first:false "lt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_float) fmt v.lt; + Pbrt.Pp.pp_record_field ~first:false "lte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_float) fmt v.lte; + Pbrt.Pp.pp_record_field ~first:false "gt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_float) fmt v.gt; + Pbrt.Pp.pp_record_field ~first:false "gte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_float) fmt v.gte; + Pbrt.Pp.pp_record_field ~first:false "in_" (Pbrt.Pp.pp_list Pbrt.Pp.pp_float) fmt v.in_; + Pbrt.Pp.pp_record_field ~first:false "not_in" (Pbrt.Pp.pp_list Pbrt.Pp.pp_float) fmt v.not_in; + Pbrt.Pp.pp_record_field ~first:false "ignore_empty" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.ignore_empty; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_double_rules fmt (v:double_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "const" (Pbrt.Pp.pp_option Pbrt.Pp.pp_float) fmt v.const; + Pbrt.Pp.pp_record_field ~first:false "lt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_float) fmt v.lt; + Pbrt.Pp.pp_record_field ~first:false "lte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_float) fmt v.lte; + Pbrt.Pp.pp_record_field ~first:false "gt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_float) fmt v.gt; + Pbrt.Pp.pp_record_field ~first:false "gte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_float) fmt v.gte; + Pbrt.Pp.pp_record_field ~first:false "in_" (Pbrt.Pp.pp_list Pbrt.Pp.pp_float) fmt v.in_; + Pbrt.Pp.pp_record_field ~first:false "not_in" (Pbrt.Pp.pp_list Pbrt.Pp.pp_float) fmt v.not_in; + Pbrt.Pp.pp_record_field ~first:false "ignore_empty" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.ignore_empty; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_int32_rules fmt (v:int32_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "const" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.const; + Pbrt.Pp.pp_record_field ~first:false "lt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.lt; + Pbrt.Pp.pp_record_field ~first:false "lte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.lte; + Pbrt.Pp.pp_record_field ~first:false "gt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.gt; + Pbrt.Pp.pp_record_field ~first:false "gte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.gte; + Pbrt.Pp.pp_record_field ~first:false "in_" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int32) fmt v.in_; + Pbrt.Pp.pp_record_field ~first:false "not_in" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int32) fmt v.not_in; + Pbrt.Pp.pp_record_field ~first:false "ignore_empty" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.ignore_empty; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_int64_rules fmt (v:int64_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "const" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.const; + Pbrt.Pp.pp_record_field ~first:false "lt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.lt; + Pbrt.Pp.pp_record_field ~first:false "lte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.lte; + Pbrt.Pp.pp_record_field ~first:false "gt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.gt; + Pbrt.Pp.pp_record_field ~first:false "gte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.gte; + Pbrt.Pp.pp_record_field ~first:false "in_" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int64) fmt v.in_; + Pbrt.Pp.pp_record_field ~first:false "not_in" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int64) fmt v.not_in; + Pbrt.Pp.pp_record_field ~first:false "ignore_empty" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.ignore_empty; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_uint32_rules fmt (v:uint32_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "const" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.const; + Pbrt.Pp.pp_record_field ~first:false "lt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.lt; + Pbrt.Pp.pp_record_field ~first:false "lte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.lte; + Pbrt.Pp.pp_record_field ~first:false "gt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.gt; + Pbrt.Pp.pp_record_field ~first:false "gte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.gte; + Pbrt.Pp.pp_record_field ~first:false "in_" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int32) fmt v.in_; + Pbrt.Pp.pp_record_field ~first:false "not_in" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int32) fmt v.not_in; + Pbrt.Pp.pp_record_field ~first:false "ignore_empty" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.ignore_empty; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_uint64_rules fmt (v:uint64_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "const" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.const; + Pbrt.Pp.pp_record_field ~first:false "lt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.lt; + Pbrt.Pp.pp_record_field ~first:false "lte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.lte; + Pbrt.Pp.pp_record_field ~first:false "gt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.gt; + Pbrt.Pp.pp_record_field ~first:false "gte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.gte; + Pbrt.Pp.pp_record_field ~first:false "in_" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int64) fmt v.in_; + Pbrt.Pp.pp_record_field ~first:false "not_in" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int64) fmt v.not_in; + Pbrt.Pp.pp_record_field ~first:false "ignore_empty" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.ignore_empty; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_sint32_rules fmt (v:sint32_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "const" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.const; + Pbrt.Pp.pp_record_field ~first:false "lt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.lt; + Pbrt.Pp.pp_record_field ~first:false "lte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.lte; + Pbrt.Pp.pp_record_field ~first:false "gt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.gt; + Pbrt.Pp.pp_record_field ~first:false "gte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.gte; + Pbrt.Pp.pp_record_field ~first:false "in_" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int32) fmt v.in_; + Pbrt.Pp.pp_record_field ~first:false "not_in" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int32) fmt v.not_in; + Pbrt.Pp.pp_record_field ~first:false "ignore_empty" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.ignore_empty; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_sint64_rules fmt (v:sint64_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "const" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.const; + Pbrt.Pp.pp_record_field ~first:false "lt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.lt; + Pbrt.Pp.pp_record_field ~first:false "lte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.lte; + Pbrt.Pp.pp_record_field ~first:false "gt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.gt; + Pbrt.Pp.pp_record_field ~first:false "gte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.gte; + Pbrt.Pp.pp_record_field ~first:false "in_" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int64) fmt v.in_; + Pbrt.Pp.pp_record_field ~first:false "not_in" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int64) fmt v.not_in; + Pbrt.Pp.pp_record_field ~first:false "ignore_empty" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.ignore_empty; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_fixed32_rules fmt (v:fixed32_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "const" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.const; + Pbrt.Pp.pp_record_field ~first:false "lt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.lt; + Pbrt.Pp.pp_record_field ~first:false "lte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.lte; + Pbrt.Pp.pp_record_field ~first:false "gt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.gt; + Pbrt.Pp.pp_record_field ~first:false "gte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.gte; + Pbrt.Pp.pp_record_field ~first:false "in_" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int32) fmt v.in_; + Pbrt.Pp.pp_record_field ~first:false "not_in" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int32) fmt v.not_in; + Pbrt.Pp.pp_record_field ~first:false "ignore_empty" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.ignore_empty; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_fixed64_rules fmt (v:fixed64_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "const" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.const; + Pbrt.Pp.pp_record_field ~first:false "lt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.lt; + Pbrt.Pp.pp_record_field ~first:false "lte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.lte; + Pbrt.Pp.pp_record_field ~first:false "gt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.gt; + Pbrt.Pp.pp_record_field ~first:false "gte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.gte; + Pbrt.Pp.pp_record_field ~first:false "in_" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int64) fmt v.in_; + Pbrt.Pp.pp_record_field ~first:false "not_in" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int64) fmt v.not_in; + Pbrt.Pp.pp_record_field ~first:false "ignore_empty" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.ignore_empty; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_sfixed32_rules fmt (v:sfixed32_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "const" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.const; + Pbrt.Pp.pp_record_field ~first:false "lt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.lt; + Pbrt.Pp.pp_record_field ~first:false "lte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.lte; + Pbrt.Pp.pp_record_field ~first:false "gt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.gt; + Pbrt.Pp.pp_record_field ~first:false "gte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.gte; + Pbrt.Pp.pp_record_field ~first:false "in_" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int32) fmt v.in_; + Pbrt.Pp.pp_record_field ~first:false "not_in" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int32) fmt v.not_in; + Pbrt.Pp.pp_record_field ~first:false "ignore_empty" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.ignore_empty; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_sfixed64_rules fmt (v:sfixed64_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "const" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.const; + Pbrt.Pp.pp_record_field ~first:false "lt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.lt; + Pbrt.Pp.pp_record_field ~first:false "lte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.lte; + Pbrt.Pp.pp_record_field ~first:false "gt" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.gt; + Pbrt.Pp.pp_record_field ~first:false "gte" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.gte; + Pbrt.Pp.pp_record_field ~first:false "in_" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int64) fmt v.in_; + Pbrt.Pp.pp_record_field ~first:false "not_in" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int64) fmt v.not_in; + Pbrt.Pp.pp_record_field ~first:false "ignore_empty" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.ignore_empty; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_bool_rules fmt (v:bool_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "const" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.const; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_known_regex fmt (v:known_regex) = + match v with + | Unknown -> Format.fprintf fmt "Unknown" + | Http_header_name -> Format.fprintf fmt "Http_header_name" + | Http_header_value -> Format.fprintf fmt "Http_header_value" + +let rec pp_string_rules_well_known fmt (v:string_rules_well_known) = + match v with + | Email x -> Format.fprintf fmt "@[Email(@,%a)@]" Pbrt.Pp.pp_bool x + | Hostname x -> Format.fprintf fmt "@[Hostname(@,%a)@]" Pbrt.Pp.pp_bool x + | Ip x -> Format.fprintf fmt "@[Ip(@,%a)@]" Pbrt.Pp.pp_bool x + | Ipv4 x -> Format.fprintf fmt "@[Ipv4(@,%a)@]" Pbrt.Pp.pp_bool x + | Ipv6 x -> Format.fprintf fmt "@[Ipv6(@,%a)@]" Pbrt.Pp.pp_bool x + | Uri x -> Format.fprintf fmt "@[Uri(@,%a)@]" Pbrt.Pp.pp_bool x + | Uri_ref x -> Format.fprintf fmt "@[Uri_ref(@,%a)@]" Pbrt.Pp.pp_bool x + | Address x -> Format.fprintf fmt "@[Address(@,%a)@]" Pbrt.Pp.pp_bool x + | Uuid x -> Format.fprintf fmt "@[Uuid(@,%a)@]" Pbrt.Pp.pp_bool x + | Well_known_regex x -> Format.fprintf fmt "@[Well_known_regex(@,%a)@]" pp_known_regex x + +and pp_string_rules fmt (v:string_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "const" (Pbrt.Pp.pp_option Pbrt.Pp.pp_string) fmt v.const; + Pbrt.Pp.pp_record_field ~first:false "len" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.len; + Pbrt.Pp.pp_record_field ~first:false "min_len" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.min_len; + Pbrt.Pp.pp_record_field ~first:false "max_len" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.max_len; + Pbrt.Pp.pp_record_field ~first:false "len_bytes" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.len_bytes; + Pbrt.Pp.pp_record_field ~first:false "min_bytes" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.min_bytes; + Pbrt.Pp.pp_record_field ~first:false "max_bytes" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.max_bytes; + Pbrt.Pp.pp_record_field ~first:false "pattern" (Pbrt.Pp.pp_option Pbrt.Pp.pp_string) fmt v.pattern; + Pbrt.Pp.pp_record_field ~first:false "prefix" (Pbrt.Pp.pp_option Pbrt.Pp.pp_string) fmt v.prefix; + Pbrt.Pp.pp_record_field ~first:false "suffix" (Pbrt.Pp.pp_option Pbrt.Pp.pp_string) fmt v.suffix; + Pbrt.Pp.pp_record_field ~first:false "contains" (Pbrt.Pp.pp_option Pbrt.Pp.pp_string) fmt v.contains; + Pbrt.Pp.pp_record_field ~first:false "not_contains" (Pbrt.Pp.pp_option Pbrt.Pp.pp_string) fmt v.not_contains; + Pbrt.Pp.pp_record_field ~first:false "in_" (Pbrt.Pp.pp_list Pbrt.Pp.pp_string) fmt v.in_; + Pbrt.Pp.pp_record_field ~first:false "not_in" (Pbrt.Pp.pp_list Pbrt.Pp.pp_string) fmt v.not_in; + Pbrt.Pp.pp_record_field ~first:false "well_known" (Pbrt.Pp.pp_option pp_string_rules_well_known) fmt v.well_known; + Pbrt.Pp.pp_record_field ~first:false "strict" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.strict; + Pbrt.Pp.pp_record_field ~first:false "ignore_empty" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.ignore_empty; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_bytes_rules_well_known fmt (v:bytes_rules_well_known) = + match v with + | Ip x -> Format.fprintf fmt "@[Ip(@,%a)@]" Pbrt.Pp.pp_bool x + | Ipv4 x -> Format.fprintf fmt "@[Ipv4(@,%a)@]" Pbrt.Pp.pp_bool x + | Ipv6 x -> Format.fprintf fmt "@[Ipv6(@,%a)@]" Pbrt.Pp.pp_bool x + +and pp_bytes_rules fmt (v:bytes_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "const" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bytes) fmt v.const; + Pbrt.Pp.pp_record_field ~first:false "len" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.len; + Pbrt.Pp.pp_record_field ~first:false "min_len" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.min_len; + Pbrt.Pp.pp_record_field ~first:false "max_len" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.max_len; + Pbrt.Pp.pp_record_field ~first:false "pattern" (Pbrt.Pp.pp_option Pbrt.Pp.pp_string) fmt v.pattern; + Pbrt.Pp.pp_record_field ~first:false "prefix" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bytes) fmt v.prefix; + Pbrt.Pp.pp_record_field ~first:false "suffix" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bytes) fmt v.suffix; + Pbrt.Pp.pp_record_field ~first:false "contains" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bytes) fmt v.contains; + Pbrt.Pp.pp_record_field ~first:false "in_" (Pbrt.Pp.pp_list Pbrt.Pp.pp_bytes) fmt v.in_; + Pbrt.Pp.pp_record_field ~first:false "not_in" (Pbrt.Pp.pp_list Pbrt.Pp.pp_bytes) fmt v.not_in; + Pbrt.Pp.pp_record_field ~first:false "well_known" (Pbrt.Pp.pp_option pp_bytes_rules_well_known) fmt v.well_known; + Pbrt.Pp.pp_record_field ~first:false "ignore_empty" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.ignore_empty; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_enum_rules fmt (v:enum_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "const" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.const; + Pbrt.Pp.pp_record_field ~first:false "defined_only" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.defined_only; + Pbrt.Pp.pp_record_field ~first:false "in_" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int32) fmt v.in_; + Pbrt.Pp.pp_record_field ~first:false "not_in" (Pbrt.Pp.pp_list Pbrt.Pp.pp_int32) fmt v.not_in; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_any_rules fmt (v:any_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "required" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.required; + Pbrt.Pp.pp_record_field ~first:false "in_" (Pbrt.Pp.pp_list Pbrt.Pp.pp_string) fmt v.in_; + Pbrt.Pp.pp_record_field ~first:false "not_in" (Pbrt.Pp.pp_list Pbrt.Pp.pp_string) fmt v.not_in; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_field_rules_type fmt (v:field_rules_type) = + match v with + | Float x -> Format.fprintf fmt "@[Float(@,%a)@]" pp_float_rules x + | Double x -> Format.fprintf fmt "@[Double(@,%a)@]" pp_double_rules x + | Int32 x -> Format.fprintf fmt "@[Int32(@,%a)@]" pp_int32_rules x + | Int64 x -> Format.fprintf fmt "@[Int64(@,%a)@]" pp_int64_rules x + | Uint32 x -> Format.fprintf fmt "@[Uint32(@,%a)@]" pp_uint32_rules x + | Uint64 x -> Format.fprintf fmt "@[Uint64(@,%a)@]" pp_uint64_rules x + | Sint32 x -> Format.fprintf fmt "@[Sint32(@,%a)@]" pp_sint32_rules x + | Sint64 x -> Format.fprintf fmt "@[Sint64(@,%a)@]" pp_sint64_rules x + | Fixed32 x -> Format.fprintf fmt "@[Fixed32(@,%a)@]" pp_fixed32_rules x + | Fixed64 x -> Format.fprintf fmt "@[Fixed64(@,%a)@]" pp_fixed64_rules x + | Sfixed32 x -> Format.fprintf fmt "@[Sfixed32(@,%a)@]" pp_sfixed32_rules x + | Sfixed64 x -> Format.fprintf fmt "@[Sfixed64(@,%a)@]" pp_sfixed64_rules x + | Bool x -> Format.fprintf fmt "@[Bool(@,%a)@]" pp_bool_rules x + | String x -> Format.fprintf fmt "@[String(@,%a)@]" pp_string_rules x + | Bytes x -> Format.fprintf fmt "@[Bytes(@,%a)@]" pp_bytes_rules x + | Enum x -> Format.fprintf fmt "@[Enum(@,%a)@]" pp_enum_rules x + | Repeated x -> Format.fprintf fmt "@[Repeated(@,%a)@]" pp_repeated_rules x + | Map x -> Format.fprintf fmt "@[Map(@,%a)@]" pp_map_rules x + | Any x -> Format.fprintf fmt "@[Any(@,%a)@]" pp_any_rules x + +and pp_field_rules fmt (v:field_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "message" (Pbrt.Pp.pp_option pp_message_rules) fmt v.message; + Pbrt.Pp.pp_record_field ~first:false "type_" (Pbrt.Pp.pp_option pp_field_rules_type) fmt v.type_; + in + Pbrt.Pp.pp_brk pp_i fmt () + +and pp_repeated_rules fmt (v:repeated_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "min_items" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.min_items; + Pbrt.Pp.pp_record_field ~first:false "max_items" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.max_items; + Pbrt.Pp.pp_record_field ~first:false "unique" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.unique; + Pbrt.Pp.pp_record_field ~first:false "items" (Pbrt.Pp.pp_option pp_field_rules) fmt v.items; + Pbrt.Pp.pp_record_field ~first:false "ignore_empty" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.ignore_empty; + in + Pbrt.Pp.pp_brk pp_i fmt () + +and pp_map_rules fmt (v:map_rules) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "min_pairs" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.min_pairs; + Pbrt.Pp.pp_record_field ~first:false "max_pairs" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int64) fmt v.max_pairs; + Pbrt.Pp.pp_record_field ~first:false "no_sparse" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.no_sparse; + Pbrt.Pp.pp_record_field ~first:false "keys" (Pbrt.Pp.pp_option pp_field_rules) fmt v.keys; + Pbrt.Pp.pp_record_field ~first:false "values" (Pbrt.Pp.pp_option pp_field_rules) fmt v.values; + Pbrt.Pp.pp_record_field ~first:false "ignore_empty" (Pbrt.Pp.pp_option Pbrt.Pp.pp_bool) fmt v.ignore_empty; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_field_options fmt (v:field_options) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "rules" (Pbrt.Pp.pp_option pp_field_rules) fmt v.rules; + in + Pbrt.Pp.pp_brk pp_i fmt () diff --git a/src/tests/expectation/validate.proto b/src/tests/expectation/validate.proto new file mode 100644 index 00000000..cb0ada05 --- /dev/null +++ b/src/tests/expectation/validate.proto @@ -0,0 +1,883 @@ +// Copyright 2024 protoc-gen-validate contributors +// Origin: https://github.com/bufbuild/protoc-gen-validate/blob/main/validate/validate.proto + +// 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. + +// NOTE: this file was modified a bit from the upstream version, extends were +// replaced with actual messages, google protobuf imports commented out, +// Duration and Timestamp rules were commented out for now. + + +syntax = "proto2"; +package validate; + +option go_package = "github.com/envoyproxy/protoc-gen-validate/validate"; +option java_package = "io.envoyproxy.pgv.validate"; + +// import "google/protobuf/descriptor.proto"; +// import "google/protobuf/duration.proto"; +// import "google/protobuf/timestamp.proto"; + +// Validation rules applied at the message level +message MessageOptions { + // Disabled nullifies any validation rules for this message, including any + // message fields associated with it that do support validation. + optional bool disabled = 1071; + // Ignore skips generation of validation methods for this message. + optional bool ignored = 1072; +} + +// Validation rules applied at the oneof level +message OneofOptions { + // Required ensures that exactly one the field options in a oneof is set; + // validation fails if no fields in the oneof are set. + optional bool required = 1071; +} + +// Validation rules applied at the field level +message FieldOptions { + // Rules specify the validations to be performed on this field. By default, + // no validation is performed against a field. + optional FieldRules rules = 1071; +} + +// FieldRules encapsulates the rules for each type of field. Depending on the +// field, the correct set should be used to ensure proper validations. +message FieldRules { + optional MessageRules message = 17; + oneof type { + // Scalar Field Types + FloatRules float = 1; + DoubleRules double = 2; + Int32Rules int32 = 3; + Int64Rules int64 = 4; + UInt32Rules uint32 = 5; + UInt64Rules uint64 = 6; + SInt32Rules sint32 = 7; + SInt64Rules sint64 = 8; + Fixed32Rules fixed32 = 9; + Fixed64Rules fixed64 = 10; + SFixed32Rules sfixed32 = 11; + SFixed64Rules sfixed64 = 12; + BoolRules bool = 13; + StringRules string = 14; + BytesRules bytes = 15; + + // Complex Field Types + EnumRules enum = 16; + RepeatedRules repeated = 18; + MapRules map = 19; + + // Well-Known Field Types + AnyRules any = 20; + //DurationRules duration = 21; + //TimestampRules timestamp = 22; + } +} + +// FloatRules describes the constraints applied to `float` values +message FloatRules { + // Const specifies that this field must be exactly the specified value + optional float const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional float lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional float lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional float gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional float gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated float in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated float not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// DoubleRules describes the constraints applied to `double` values +message DoubleRules { + // Const specifies that this field must be exactly the specified value + optional double const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional double lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional double lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional double gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional double gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated double in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated double not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// Int32Rules describes the constraints applied to `int32` values +message Int32Rules { + // Const specifies that this field must be exactly the specified value + optional int32 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional int32 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional int32 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional int32 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional int32 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated int32 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated int32 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// Int64Rules describes the constraints applied to `int64` values +message Int64Rules { + // Const specifies that this field must be exactly the specified value + optional int64 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional int64 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional int64 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional int64 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional int64 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated int64 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated int64 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// UInt32Rules describes the constraints applied to `uint32` values +message UInt32Rules { + // Const specifies that this field must be exactly the specified value + optional uint32 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional uint32 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional uint32 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional uint32 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional uint32 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated uint32 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated uint32 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// UInt64Rules describes the constraints applied to `uint64` values +message UInt64Rules { + // Const specifies that this field must be exactly the specified value + optional uint64 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional uint64 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional uint64 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional uint64 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional uint64 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated uint64 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated uint64 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// SInt32Rules describes the constraints applied to `sint32` values +message SInt32Rules { + // Const specifies that this field must be exactly the specified value + optional sint32 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional sint32 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional sint32 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional sint32 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional sint32 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated sint32 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated sint32 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// SInt64Rules describes the constraints applied to `sint64` values +message SInt64Rules { + // Const specifies that this field must be exactly the specified value + optional sint64 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional sint64 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional sint64 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional sint64 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional sint64 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated sint64 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated sint64 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// Fixed32Rules describes the constraints applied to `fixed32` values +message Fixed32Rules { + // Const specifies that this field must be exactly the specified value + optional fixed32 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional fixed32 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional fixed32 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional fixed32 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional fixed32 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated fixed32 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated fixed32 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// Fixed64Rules describes the constraints applied to `fixed64` values +message Fixed64Rules { + // Const specifies that this field must be exactly the specified value + optional fixed64 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional fixed64 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional fixed64 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional fixed64 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional fixed64 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated fixed64 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated fixed64 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// SFixed32Rules describes the constraints applied to `sfixed32` values +message SFixed32Rules { + // Const specifies that this field must be exactly the specified value + optional sfixed32 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional sfixed32 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional sfixed32 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional sfixed32 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional sfixed32 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated sfixed32 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated sfixed32 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// SFixed64Rules describes the constraints applied to `sfixed64` values +message SFixed64Rules { + // Const specifies that this field must be exactly the specified value + optional sfixed64 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional sfixed64 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional sfixed64 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional sfixed64 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional sfixed64 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated sfixed64 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated sfixed64 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// BoolRules describes the constraints applied to `bool` values +message BoolRules { + // Const specifies that this field must be exactly the specified value + optional bool const = 1; +} + +// StringRules describe the constraints applied to `string` values +message StringRules { + // Const specifies that this field must be exactly the specified value + optional string const = 1; + + // Len specifies that this field must be the specified number of + // characters (Unicode code points). Note that the number of + // characters may differ from the number of bytes in the string. + optional uint64 len = 19; + + // MinLen specifies that this field must be the specified number of + // characters (Unicode code points) at a minimum. Note that the number of + // characters may differ from the number of bytes in the string. + optional uint64 min_len = 2; + + // MaxLen specifies that this field must be the specified number of + // characters (Unicode code points) at a maximum. Note that the number of + // characters may differ from the number of bytes in the string. + optional uint64 max_len = 3; + + // LenBytes specifies that this field must be the specified number of bytes + optional uint64 len_bytes = 20; + + // MinBytes specifies that this field must be the specified number of bytes + // at a minimum + optional uint64 min_bytes = 4; + + // MaxBytes specifies that this field must be the specified number of bytes + // at a maximum + optional uint64 max_bytes = 5; + + // Pattern specifies that this field must match against the specified + // regular expression (RE2 syntax). The included expression should elide + // any delimiters. + optional string pattern = 6; + + // Prefix specifies that this field must have the specified substring at + // the beginning of the string. + optional string prefix = 7; + + // Suffix specifies that this field must have the specified substring at + // the end of the string. + optional string suffix = 8; + + // Contains specifies that this field must have the specified substring + // anywhere in the string. + optional string contains = 9; + + // NotContains specifies that this field cannot have the specified substring + // anywhere in the string. + optional string not_contains = 23; + + // In specifies that this field must be equal to one of the specified + // values + repeated string in = 10; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated string not_in = 11; + + // WellKnown rules provide advanced constraints against common string + // patterns + oneof well_known { + // Email specifies that the field must be a valid email address as + // defined by RFC 5322 + bool email = 12; + + // Hostname specifies that the field must be a valid hostname as + // defined by RFC 1034. This constraint does not support + // internationalized domain names (IDNs). + bool hostname = 13; + + // Ip specifies that the field must be a valid IP (v4 or v6) address. + // Valid IPv6 addresses should not include surrounding square brackets. + bool ip = 14; + + // Ipv4 specifies that the field must be a valid IPv4 address. + bool ipv4 = 15; + + // Ipv6 specifies that the field must be a valid IPv6 address. Valid + // IPv6 addresses should not include surrounding square brackets. + bool ipv6 = 16; + + // Uri specifies that the field must be a valid, absolute URI as defined + // by RFC 3986 + bool uri = 17; + + // UriRef specifies that the field must be a valid URI as defined by RFC + // 3986 and may be relative or absolute. + bool uri_ref = 18; + + // Address specifies that the field must be either a valid hostname as + // defined by RFC 1034 (which does not support internationalized domain + // names or IDNs), or it can be a valid IP (v4 or v6). + bool address = 21; + + // Uuid specifies that the field must be a valid UUID as defined by + // RFC 4122 + bool uuid = 22; + + // WellKnownRegex specifies a common well known pattern defined as a regex. + KnownRegex well_known_regex = 24; + } + + // This applies to regexes HTTP_HEADER_NAME and HTTP_HEADER_VALUE to enable + // strict header validation. + // By default, this is true, and HTTP header validations are RFC-compliant. + // Setting to false will enable a looser validations that only disallows + // \r\n\0 characters, which can be used to bypass header matching rules. + optional bool strict = 25 [default = true]; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 26; +} + +// WellKnownRegex contain some well-known patterns. +enum KnownRegex { + UNKNOWN = 0; + + // HTTP header name as defined by RFC 7230. + HTTP_HEADER_NAME = 1; + + // HTTP header value as defined by RFC 7230. + HTTP_HEADER_VALUE = 2; +} + +// BytesRules describe the constraints applied to `bytes` values +message BytesRules { + // Const specifies that this field must be exactly the specified value + optional bytes const = 1; + + // Len specifies that this field must be the specified number of bytes + optional uint64 len = 13; + + // MinLen specifies that this field must be the specified number of bytes + // at a minimum + optional uint64 min_len = 2; + + // MaxLen specifies that this field must be the specified number of bytes + // at a maximum + optional uint64 max_len = 3; + + // Pattern specifies that this field must match against the specified + // regular expression (RE2 syntax). The included expression should elide + // any delimiters. + optional string pattern = 4; + + // Prefix specifies that this field must have the specified bytes at the + // beginning of the string. + optional bytes prefix = 5; + + // Suffix specifies that this field must have the specified bytes at the + // end of the string. + optional bytes suffix = 6; + + // Contains specifies that this field must have the specified bytes + // anywhere in the string. + optional bytes contains = 7; + + // In specifies that this field must be equal to one of the specified + // values + repeated bytes in = 8; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated bytes not_in = 9; + + // WellKnown rules provide advanced constraints against common byte + // patterns + oneof well_known { + // Ip specifies that the field must be a valid IP (v4 or v6) address in + // byte format + bool ip = 10; + + // Ipv4 specifies that the field must be a valid IPv4 address in byte + // format + bool ipv4 = 11; + + // Ipv6 specifies that the field must be a valid IPv6 address in byte + // format + bool ipv6 = 12; + } + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 14; +} + +// EnumRules describe the constraints applied to enum values +message EnumRules { + // Const specifies that this field must be exactly the specified value + optional int32 const = 1; + + // DefinedOnly specifies that this field must be only one of the defined + // values for this enum, failing on any undefined value. + optional bool defined_only = 2; + + // In specifies that this field must be equal to one of the specified + // values + repeated int32 in = 3; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated int32 not_in = 4; +} + +// MessageRules describe the constraints applied to embedded message values. +// For message-type fields, validation is performed recursively. +message MessageRules { + // Skip specifies that the validation rules of this field should not be + // evaluated + optional bool skip = 1; + + // Required specifies that this field must be set + optional bool required = 2; +} + +// RepeatedRules describe the constraints applied to `repeated` values +message RepeatedRules { + // MinItems specifies that this field must have the specified number of + // items at a minimum + optional uint64 min_items = 1; + + // MaxItems specifies that this field must have the specified number of + // items at a maximum + optional uint64 max_items = 2; + + // Unique specifies that all elements in this field must be unique. This + // constraint is only applicable to scalar and enum types (messages are not + // supported). + optional bool unique = 3; + + // Items specifies the constraints to be applied to each item in the field. + // Repeated message fields will still execute validation against each item + // unless skip is specified here. + optional FieldRules items = 4; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 5; +} + +// MapRules describe the constraints applied to `map` values +message MapRules { + // MinPairs specifies that this field must have the specified number of + // KVs at a minimum + optional uint64 min_pairs = 1; + + // MaxPairs specifies that this field must have the specified number of + // KVs at a maximum + optional uint64 max_pairs = 2; + + // NoSparse specifies values in this field cannot be unset. This only + // applies to map's with message value types. + optional bool no_sparse = 3; + + // Keys specifies the constraints to be applied to each key in the field. + optional FieldRules keys = 4; + + // Values specifies the constraints to be applied to the value of each key + // in the field. Message values will still have their validations evaluated + // unless skip is specified here. + optional FieldRules values = 5; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 6; +} + +// AnyRules describe constraints applied exclusively to the +// `google.protobuf.Any` well-known type +message AnyRules { + // Required specifies that this field must be set + optional bool required = 1; + + // In specifies that this field's `type_url` must be equal to one of the + // specified values. + repeated string in = 2; + + // NotIn specifies that this field's `type_url` must not be equal to any of + // the specified values. + repeated string not_in = 3; +} + +// // DurationRules describe the constraints applied exclusively to the +// // `google.protobuf.Duration` well-known type +// message DurationRules { +// // Required specifies that this field must be set +// optional bool required = 1; +// +// // Const specifies that this field must be exactly the specified value +// optional google.protobuf.Duration const = 2; +// +// // Lt specifies that this field must be less than the specified value, +// // exclusive +// optional google.protobuf.Duration lt = 3; +// +// // Lt specifies that this field must be less than the specified value, +// // inclusive +// optional google.protobuf.Duration lte = 4; +// +// // Gt specifies that this field must be greater than the specified value, +// // exclusive +// optional google.protobuf.Duration gt = 5; +// +// // Gte specifies that this field must be greater than the specified value, +// // inclusive +// optional google.protobuf.Duration gte = 6; +// +// // In specifies that this field must be equal to one of the specified +// // values +// repeated google.protobuf.Duration in = 7; +// +// // NotIn specifies that this field cannot be equal to one of the specified +// // values +// repeated google.protobuf.Duration not_in = 8; +// } +// +// // TimestampRules describe the constraints applied exclusively to the +// // `google.protobuf.Timestamp` well-known type +// message TimestampRules { +// // Required specifies that this field must be set +// optional bool required = 1; +// +// // Const specifies that this field must be exactly the specified value +// optional google.protobuf.Timestamp const = 2; +// +// // Lt specifies that this field must be less than the specified value, +// // exclusive +// optional google.protobuf.Timestamp lt = 3; +// +// // Lte specifies that this field must be less than the specified value, +// // inclusive +// optional google.protobuf.Timestamp lte = 4; +// +// // Gt specifies that this field must be greater than the specified value, +// // exclusive +// optional google.protobuf.Timestamp gt = 5; +// +// // Gte specifies that this field must be greater than the specified value, +// // inclusive +// optional google.protobuf.Timestamp gte = 6; +// +// // LtNow specifies that this must be less than the current time. LtNow +// // can only be used with the Within rule. +// optional bool lt_now = 7; +// +// // GtNow specifies that this must be greater than the current time. GtNow +// // can only be used with the Within rule. +// optional bool gt_now = 8; +// +// // Within specifies that this field must be within this duration of the +// // current time. This constraint can be used alone or with the LtNow and +// // GtNow rules. +// optional google.protobuf.Duration within = 9; +// } +// \ No newline at end of file