diff --git a/src/compilerlib/pb_codegen_backend.ml b/src/compilerlib/pb_codegen_backend.ml index 14194ced..81a721e2 100644 --- a/src/compilerlib/pb_codegen_backend.ml +++ b/src/compilerlib/pb_codegen_backend.ml @@ -411,21 +411,6 @@ let compile_message ~(unsigned_tag : bool) (file_options : Pb_option.set) } in [ type_ ] - | Tt.Message_oneof_field f :: [] -> - let outer_message_names = message_names @ [ message_name ] in - let variant = - variant_of_oneof ~unsigned_tag ~outer_message_names ~all_types - file_options file_name f - in - [ - Ot. - { - module_prefix; - spec = Variant variant; - type_level_ppx_extension; - type_options = message_options; - }; - ] | _ -> let variants, fields = List.fold_left diff --git a/src/compilerlib/pb_codegen_decode_binary.ml b/src/compilerlib/pb_codegen_decode_binary.ml index f9e98225..b7d994b1 100644 --- a/src/compilerlib/pb_codegen_decode_binary.ml +++ b/src/compilerlib/pb_codegen_decode_binary.ml @@ -169,9 +169,9 @@ let gen_rft_variant sc r_name rf_label { Ot.v_constructors; _ } = match vc_field_type with | Ot.Vct_nullary -> F.line sc "Pbrt.Decoder.empty_nested d;"; - F.linep sc "v.%s <- %s;" rf_label vc_constructor + F.linep sc "v.%s <- Some %s;" rf_label vc_constructor | Ot.Vct_non_nullary_constructor field_type -> - F.linep sc "v.%s <- %s (%s);" rf_label vc_constructor + F.linep sc "v.%s <- Some (%s (%s));" rf_label vc_constructor (decode_field_expression field_type pk))) v_constructors diff --git a/src/compilerlib/pb_codegen_decode_bs.ml b/src/compilerlib/pb_codegen_decode_bs.ml index 645f782d..7a8c74cd 100644 --- a/src/compilerlib/pb_codegen_decode_bs.ml +++ b/src/compilerlib/pb_codegen_decode_bs.ml @@ -94,12 +94,14 @@ let gen_rft_variant sc ~r_name ~rf_label { Ot.v_constructors; _ } = match vc_field_type with | Ot.Vct_nullary -> - F.linep sc "| \"%s\" -> v.%s <- %s" json_label rf_label vc_constructor + F.linep sc "| \"%s\" -> v.%s <- Some %s" json_label rf_label + vc_constructor | Ot.Vct_non_nullary_constructor field_type -> let value_expression = value_expression ~r_name ~rf_label field_type in F.linep sc "| \"%s\" -> " json_label; F.linep sc " let json = Js.Dict.unsafeGet json \"%s\" in" json_label; - F.linep sc " v.%s <- %s (%s)" rf_label vc_constructor value_expression) + F.linep sc " v.%s <- Some (%s (%s))" rf_label vc_constructor + value_expression) v_constructors (* Generate decode function for a record *) diff --git a/src/compilerlib/pb_codegen_decode_yojson.ml b/src/compilerlib/pb_codegen_decode_yojson.ml index cd9a2e1a..2092c169 100644 --- a/src/compilerlib/pb_codegen_decode_yojson.ml +++ b/src/compilerlib/pb_codegen_decode_yojson.ml @@ -89,14 +89,14 @@ let gen_rft_variant_field sc ~r_name ~rf_label { Ot.v_constructors; _ } = match vc_field_type with | Ot.Vct_nullary -> - F.linep sc "| (\"%s\", _) -> v.%s <- %s" json_label rf_label + F.linep sc "| (\"%s\", _) -> v.%s <- Some %s" json_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) -> " json_label match_variable_name; - F.linep sc " v.%s <- %s (%s)" rf_label vc_constructor exp) + 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 = diff --git a/src/compilerlib/pb_codegen_default.ml b/src/compilerlib/pb_codegen_default.ml index 19d0b4af..70f6cb3f 100644 --- a/src/compilerlib/pb_codegen_default.ml +++ b/src/compilerlib/pb_codegen_default.ml @@ -69,14 +69,7 @@ let record_field_default_info record_field = | Ot.At_hashtable -> "Hashtbl.create 128") (* TODO This initial value could be configurable either via * the default function or via a protobuf option. *) - | Ot.Rft_variant { Ot.v_constructors; _ } -> - (match v_constructors with - | [] -> assert false - | { Ot.vc_constructor; vc_field_type; _ } :: _ -> - (match vc_field_type with - | Ot.Vct_nullary -> vc_constructor - | Ot.Vct_non_nullary_constructor field_type -> - sp "%s (%s)" vc_constructor (dfvft field_type None))) + | Ot.Rft_variant _ -> "None" in field_name, default_value, type_string diff --git a/src/compilerlib/pb_codegen_encode_binary.ml b/src/compilerlib/pb_codegen_encode_binary.ml index 3dcb7b1c..3e61409a 100644 --- a/src/compilerlib/pb_codegen_encode_binary.ml +++ b/src/compilerlib/pb_codegen_encode_binary.ml @@ -145,16 +145,17 @@ let gen_rft_variant sc var_name { Ot.v_constructors; _ } = match vc_field_type with | Ot.Vct_nullary -> - F.linep sc "| %s ->" vc_constructor; + F.linep sc "| Some %s ->" vc_constructor; F.sub_scope sc (fun sc -> F.line sc "Pbrt.Encoder.empty_nested encoder;"; gen_encode_field_key sc vc_encoding_number vc_payload_kind false) | Ot.Vct_non_nullary_constructor field_type -> - F.linep sc "| %s x ->" vc_constructor; + F.linep sc "| Some %s x ->" vc_constructor; F.sub_scope sc (fun sc -> gen_encode_field_type sc ~with_key:true "x" vc_encoding_number vc_payload_kind false field_type)) v_constructors; + F.line sc "| None -> ()"; F.line sc "end;" let gen_rft_associative sc var_name associative_field = diff --git a/src/compilerlib/pb_codegen_encode_bs.ml b/src/compilerlib/pb_codegen_encode_bs.ml index 5c30c9cd..5798d6ba 100644 --- a/src/compilerlib/pb_codegen_encode_bs.ml +++ b/src/compilerlib/pb_codegen_encode_bs.ml @@ -162,14 +162,15 @@ let gen_rft_variant sc var_name rf_label { Ot.v_constructors; _ } = let json_label = Pb_codegen_util.camel_case_of_constructor vc_constructor in - F.linep sc "| %s v ->" vc_constructor; + F.linep sc "| Some (%s v) ->" vc_constructor; F.sub_scope sc (fun sc -> match vc_field_type with | Ot.Vct_nullary -> F.linep sc "Js.Dict.set json \"%s\" Js.Json.null" json_label | Ot.Vct_non_nullary_constructor field_type -> gen_field sc var_name json_label field_type vc_payload_kind)) - v_constructors); + v_constructors; + F.line sc "| None -> ()"); F.linep sc "end; (* match v.%s *)" rf_label let gen_record ?and_ { Ot.r_name; r_fields } sc = diff --git a/src/compilerlib/pb_codegen_encode_yojson.ml b/src/compilerlib/pb_codegen_encode_yojson.ml index bb3f7d06..25ecce40 100644 --- a/src/compilerlib/pb_codegen_encode_yojson.ml +++ b/src/compilerlib/pb_codegen_encode_yojson.ml @@ -133,7 +133,7 @@ let gen_rft_variant sc rf_label { Ot.v_constructors; _ } = let json_label = Pb_codegen_util.camel_case_of_constructor vc_constructor in - F.linep sc "| %s v ->" vc_constructor; + F.linep sc "| Some (%s v) ->" vc_constructor; F.sub_scope sc (fun sc -> match vc_field_type with | Ot.Vct_nullary -> @@ -144,7 +144,8 @@ let gen_rft_variant sc rf_label { Ot.v_constructors; _ } = with | None -> F.linep sc "(\"%s\", `Null) :: assoc" json_label | Some exp -> F.linep sc "%s :: assoc " exp))) - v_constructors); + v_constructors; + F.line sc "| None -> assoc"); F.linep sc "in (* match v.%s *)" rf_label diff --git a/src/compilerlib/pb_codegen_pp.ml b/src/compilerlib/pb_codegen_pp.ml index fdbefc49..9d53cf8e 100644 --- a/src/compilerlib/pb_codegen_pp.ml +++ b/src/compilerlib/pb_codegen_pp.ml @@ -66,7 +66,9 @@ let gen_record ?and_ { Ot.r_name; r_fields } sc = * requirement is indeed comming from the imposed Protobuf format) *) F.line sc - @@ sp "Pbrt.Pp.pp_record_field ~first:%b \"%s\" %s fmt %s;" + @@ sp + "Pbrt.Pp.pp_record_field ~first:%b \"%s\" \ + (Pbrt.Pp.pp_option %s) fmt %s;" first rf_label ("pp_" ^ v_name) var_name (* Rft_variant_field *) | Ot.Rft_associative (at, _, (key_type, _), (value_type, _)) -> diff --git a/src/compilerlib/pb_codegen_util.ml b/src/compilerlib/pb_codegen_util.ml index 0cb6a987..7a3bcef7 100644 --- a/src/compilerlib/pb_codegen_util.ml +++ b/src/compilerlib/pb_codegen_util.ml @@ -68,8 +68,8 @@ let string_of_record_field_type ?module_prefix = function (string_of_associative_type Ot.At_hashtable) | Ot.Rft_variant { Ot.v_name; _ } -> (match module_prefix with - | None -> v_name - | Some module_prefix -> module_prefix ^ "." ^ v_name) + | None -> v_name ^ " option" + | Some module_prefix -> module_prefix ^ "." ^ v_name ^ " option") (** [function_name_of_user_defined prefix user_defined] returns the function name of the form `(module'.'?)prefix_(type_name)`. diff --git a/src/examples/dune b/src/examples/dune index f97e3502..24d338af 100644 --- a/src/examples/dune +++ b/src/examples/dune @@ -94,6 +94,18 @@ (package ocaml-protoc) (libraries pbrt pbrt_yojson pbrt_services)) +(rule + (targets oneof.ml oneof.mli) + (deps oneof.proto) + (action + (run ocaml-protoc --binary --pp --yojson --services --ml_out ./ %{deps}))) + +(test + (name oneof) + (modules oneof) ; just check that it compiles + (package ocaml-protoc) + (libraries pbrt pbrt_yojson pbrt_services)) + (include dune.inc) (rule @@ -116,4 +128,5 @@ example04 example05 file_server - orgchart)))) + orgchart + oneof)))) diff --git a/src/examples/dune.inc b/src/examples/dune.inc index e74bd2b6..517799ce 100644 --- a/src/examples/dune.inc +++ b/src/examples/dune.inc @@ -70,6 +70,16 @@ (action (diff file_server.mli.expected file_server.mli))) +(rule + (alias runtest) + (action + (diff oneof.ml.expected oneof.ml))) + +(rule + (alias runtest) + (action + (diff oneof.mli.expected oneof.mli))) + (rule (alias runtest) (action diff --git a/src/examples/example03.ml.expected b/src/examples/example03.ml.expected index 24f42961..5b8cc697 100644 --- a/src/examples/example03.ml.expected +++ b/src/examples/example03.ml.expected @@ -2,13 +2,23 @@ type string_some_none = unit -type string_some = +type string_some_t = | None | Some of string +and string_some = { + t : string_some_t option; +} + let rec default_string_some_none = () -let rec default_string_some (): string_some = None +let rec default_string_some_t (): string_some_t = None + +and default_string_some + ?t:((t:string_some_t option) = None) + () : string_some = { + t; +} [@@@ocaml.warning "-27-30-39"] @@ -20,7 +30,13 @@ let rec pp_string_some_none fmt (v:string_some_none) = in Pbrt.Pp.pp_brk pp_i fmt () -let rec pp_string_some fmt (v:string_some) = +let rec pp_string_some_t fmt (v:string_some_t) = match v with | None -> Format.fprintf fmt "None" | Some x -> Format.fprintf fmt "@[Some(@,%a)@]" Pbrt.Pp.pp_string x + +and pp_string_some fmt (v:string_some) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "t" (Pbrt.Pp.pp_option pp_string_some_t) fmt v.t; + in + Pbrt.Pp.pp_brk pp_i fmt () diff --git a/src/examples/example03.mli.expected b/src/examples/example03.mli.expected index 6911af79..ffee5707 100644 --- a/src/examples/example03.mli.expected +++ b/src/examples/example03.mli.expected @@ -9,17 +9,27 @@ type string_some_none = unit -type string_some = +type string_some_t = | None | Some of string +and string_some = { + t : string_some_t option; +} + (** {2 Basic values} *) val default_string_some_none : unit (** [default_string_some_none ()] is the default value for type [string_some_none] *) -val default_string_some : unit -> string_some +val default_string_some_t : unit -> string_some_t +(** [default_string_some_t ()] is the default value for type [string_some_t] *) + +val default_string_some : + ?t:string_some_t option -> + unit -> + string_some (** [default_string_some ()] is the default value for type [string_some] *) @@ -28,5 +38,8 @@ val default_string_some : unit -> string_some val pp_string_some_none : Format.formatter -> string_some_none -> unit (** [pp_string_some_none v] formats v *) +val pp_string_some_t : Format.formatter -> string_some_t -> unit +(** [pp_string_some_t v] formats v *) + val pp_string_some : Format.formatter -> string_some -> unit (** [pp_string_some v] formats v *) diff --git a/src/examples/example04.ml.expected b/src/examples/example04.ml.expected index 0f9f6b90..ee2b3158 100644 --- a/src/examples/example04.ml.expected +++ b/src/examples/example04.ml.expected @@ -7,10 +7,14 @@ type int_list_cons = { next : int_list; } -and int_list = +and int_list_t = | Cons of int_list_cons | Nil +and int_list = { + t : int_list_t option; +} + let rec default_int_list_nil = () let rec default_int_list_cons @@ -21,7 +25,13 @@ let rec default_int_list_cons next; } -and default_int_list () : int_list = Cons (default_int_list_cons ()) +and default_int_list_t () : int_list_t = Cons (default_int_list_cons ()) + +and default_int_list + ?t:((t:int_list_t option) = None) + () : int_list = { + t; +} [@@@ocaml.warning "-27-30-39"] @@ -40,7 +50,13 @@ let rec pp_int_list_cons fmt (v:int_list_cons) = in Pbrt.Pp.pp_brk pp_i fmt () -and pp_int_list fmt (v:int_list) = +and pp_int_list_t fmt (v:int_list_t) = match v with | Cons x -> Format.fprintf fmt "@[Cons(@,%a)@]" pp_int_list_cons x | Nil -> Format.fprintf fmt "Nil" + +and pp_int_list fmt (v:int_list) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "t" (Pbrt.Pp.pp_option pp_int_list_t) fmt v.t; + in + Pbrt.Pp.pp_brk pp_i fmt () diff --git a/src/examples/example04.mli.expected b/src/examples/example04.mli.expected index 1b65cb51..71dd0192 100644 --- a/src/examples/example04.mli.expected +++ b/src/examples/example04.mli.expected @@ -14,10 +14,14 @@ type int_list_cons = { next : int_list; } -and int_list = +and int_list_t = | Cons of int_list_cons | Nil +and int_list = { + t : int_list_t option; +} + (** {2 Basic values} *) @@ -31,7 +35,13 @@ val default_int_list_cons : int_list_cons (** [default_int_list_cons ()] is the default value for type [int_list_cons] *) -val default_int_list : unit -> int_list +val default_int_list_t : unit -> int_list_t +(** [default_int_list_t ()] is the default value for type [int_list_t] *) + +val default_int_list : + ?t:int_list_t option -> + unit -> + int_list (** [default_int_list ()] is the default value for type [int_list] *) @@ -43,5 +53,8 @@ val pp_int_list_nil : Format.formatter -> int_list_nil -> unit val pp_int_list_cons : Format.formatter -> int_list_cons -> unit (** [pp_int_list_cons v] formats v *) +val pp_int_list_t : Format.formatter -> int_list_t -> unit +(** [pp_int_list_t v] formats v *) + val pp_int_list : Format.formatter -> int_list -> unit (** [pp_int_list v] formats v *) diff --git a/src/examples/oneof.ml.expected b/src/examples/oneof.ml.expected new file mode 100644 index 00000000..ec600fde --- /dev/null +++ b/src/examples/oneof.ml.expected @@ -0,0 +1,416 @@ +[@@@ocaml.warning "-27-30-39"] + +type patch_copy = { + start : int64; + end_ : int64; +} + +type patch_insert = { + raw_bytes : bytes; +} + +type patch_op = + | Copy_op of patch_copy + | Insert_op of patch_insert + +and patch = { + op : patch_op option; + id : int64; +} + +type instructions = { + operations : patch list; +} + +let rec default_patch_copy + ?start:((start:int64) = 0L) + ?end_:((end_:int64) = 0L) + () : patch_copy = { + start; + end_; +} + +let rec default_patch_insert + ?raw_bytes:((raw_bytes:bytes) = Bytes.create 0) + () : patch_insert = { + raw_bytes; +} + +let rec default_patch_op () : patch_op = Copy_op (default_patch_copy ()) + +and default_patch + ?op:((op:patch_op option) = None) + ?id:((id:int64) = 0L) + () : patch = { + op; + id; +} + +let rec default_instructions + ?operations:((operations:patch list) = []) + () : instructions = { + operations; +} + +type patch_copy_mutable = { + mutable start : int64; + mutable end_ : int64; +} + +let default_patch_copy_mutable () : patch_copy_mutable = { + start = 0L; + end_ = 0L; +} + +type patch_insert_mutable = { + mutable raw_bytes : bytes; +} + +let default_patch_insert_mutable () : patch_insert_mutable = { + raw_bytes = Bytes.create 0; +} + +type patch_mutable = { + mutable op : patch_op option; + mutable id : int64; +} + +let default_patch_mutable () : patch_mutable = { + op = None; + id = 0L; +} + +type instructions_mutable = { + mutable operations : patch list; +} + +let default_instructions_mutable () : instructions_mutable = { + operations = []; +} + +[@@@ocaml.warning "-27-30-39"] + +(** {2 Formatters} *) + +let rec pp_patch_copy fmt (v:patch_copy) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "start" Pbrt.Pp.pp_int64 fmt v.start; + Pbrt.Pp.pp_record_field ~first:false "end_" Pbrt.Pp.pp_int64 fmt v.end_; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_patch_insert fmt (v:patch_insert) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "raw_bytes" Pbrt.Pp.pp_bytes fmt v.raw_bytes; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_patch_op fmt (v:patch_op) = + match v with + | Copy_op x -> Format.fprintf fmt "@[Copy_op(@,%a)@]" pp_patch_copy x + | Insert_op x -> Format.fprintf fmt "@[Insert_op(@,%a)@]" pp_patch_insert x + +and pp_patch fmt (v:patch) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "op" (Pbrt.Pp.pp_option pp_patch_op) fmt v.op; + Pbrt.Pp.pp_record_field ~first:false "id" Pbrt.Pp.pp_int64 fmt v.id; + in + Pbrt.Pp.pp_brk pp_i fmt () + +let rec pp_instructions fmt (v:instructions) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "operations" (Pbrt.Pp.pp_list pp_patch) fmt v.operations; + in + Pbrt.Pp.pp_brk pp_i fmt () + +[@@@ocaml.warning "-27-30-39"] + +(** {2 Protobuf Encoding} *) + +let rec encode_pb_patch_copy (v:patch_copy) encoder = + Pbrt.Encoder.int64_as_varint v.start encoder; + Pbrt.Encoder.key 1 Pbrt.Varint encoder; + Pbrt.Encoder.int64_as_varint v.end_ encoder; + Pbrt.Encoder.key 2 Pbrt.Varint encoder; + () + +let rec encode_pb_patch_insert (v:patch_insert) encoder = + Pbrt.Encoder.bytes v.raw_bytes encoder; + Pbrt.Encoder.key 1 Pbrt.Bytes encoder; + () + +let rec encode_pb_patch_op (v:patch_op) encoder = + begin match v with + | Copy_op x -> + Pbrt.Encoder.nested encode_pb_patch_copy x encoder; + Pbrt.Encoder.key 3 Pbrt.Bytes encoder; + | Insert_op x -> + Pbrt.Encoder.nested encode_pb_patch_insert x encoder; + Pbrt.Encoder.key 4 Pbrt.Bytes encoder; + end + +and encode_pb_patch (v:patch) encoder = + begin match v.op with + | Some Copy_op x -> + Pbrt.Encoder.nested encode_pb_patch_copy x encoder; + Pbrt.Encoder.key 3 Pbrt.Bytes encoder; + | Some Insert_op x -> + Pbrt.Encoder.nested encode_pb_patch_insert x encoder; + Pbrt.Encoder.key 4 Pbrt.Bytes encoder; + | None -> () + end; + Pbrt.Encoder.int64_as_varint v.id encoder; + Pbrt.Encoder.key 5 Pbrt.Varint encoder; + () + +let rec encode_pb_instructions (v:instructions) encoder = + Pbrt.List_util.rev_iter_with (fun x encoder -> + Pbrt.Encoder.nested encode_pb_patch x encoder; + Pbrt.Encoder.key 1 Pbrt.Bytes encoder; + ) v.operations encoder; + () + +[@@@ocaml.warning "-27-30-39"] + +(** {2 Protobuf Decoding} *) + +let rec decode_pb_patch_copy d = + let v = default_patch_copy_mutable () in + let continue__= ref true in + while !continue__ do + match Pbrt.Decoder.key d with + | None -> ( + ); continue__ := false + | Some (1, Pbrt.Varint) -> begin + v.start <- Pbrt.Decoder.int64_as_varint d; + end + | Some (1, pk) -> + Pbrt.Decoder.unexpected_payload "Message(patch_copy), field(1)" pk + | Some (2, Pbrt.Varint) -> begin + v.end_ <- Pbrt.Decoder.int64_as_varint d; + end + | Some (2, pk) -> + Pbrt.Decoder.unexpected_payload "Message(patch_copy), field(2)" pk + | Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind + done; + ({ + start = v.start; + end_ = v.end_; + } : patch_copy) + +let rec decode_pb_patch_insert d = + let v = default_patch_insert_mutable () in + let continue__= ref true in + while !continue__ do + match Pbrt.Decoder.key d with + | None -> ( + ); continue__ := false + | Some (1, Pbrt.Bytes) -> begin + v.raw_bytes <- Pbrt.Decoder.bytes d; + end + | Some (1, pk) -> + Pbrt.Decoder.unexpected_payload "Message(patch_insert), field(1)" pk + | Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind + done; + ({ + raw_bytes = v.raw_bytes; + } : patch_insert) + +let rec decode_pb_patch_op d = + let rec loop () = + let ret:patch_op = match Pbrt.Decoder.key d with + | None -> Pbrt.Decoder.malformed_variant "patch_op" + | Some (3, _) -> (Copy_op (decode_pb_patch_copy (Pbrt.Decoder.nested d)) : patch_op) + | Some (4, _) -> (Insert_op (decode_pb_patch_insert (Pbrt.Decoder.nested d)) : patch_op) + | Some (n, payload_kind) -> ( + Pbrt.Decoder.skip d payload_kind; + loop () + ) + in + ret + in + loop () + +and decode_pb_patch d = + let v = default_patch_mutable () in + let continue__= ref true in + while !continue__ do + match Pbrt.Decoder.key d with + | None -> ( + ); continue__ := false + | Some (3, Pbrt.Bytes) -> begin + v.op <- Some (Copy_op (decode_pb_patch_copy (Pbrt.Decoder.nested d))); + end + | Some (3, pk) -> + Pbrt.Decoder.unexpected_payload "Message(patch), field(3)" pk + | Some (4, Pbrt.Bytes) -> begin + v.op <- Some (Insert_op (decode_pb_patch_insert (Pbrt.Decoder.nested d))); + end + | Some (4, pk) -> + Pbrt.Decoder.unexpected_payload "Message(patch), field(4)" pk + | Some (5, Pbrt.Varint) -> begin + v.id <- Pbrt.Decoder.int64_as_varint d; + end + | Some (5, pk) -> + Pbrt.Decoder.unexpected_payload "Message(patch), field(5)" pk + | Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind + done; + ({ + op = v.op; + id = v.id; + } : patch) + +let rec decode_pb_instructions d = + let v = default_instructions_mutable () in + let continue__= ref true in + while !continue__ do + match Pbrt.Decoder.key d with + | None -> ( + v.operations <- List.rev v.operations; + ); continue__ := false + | Some (1, Pbrt.Bytes) -> begin + v.operations <- (decode_pb_patch (Pbrt.Decoder.nested d)) :: v.operations; + end + | Some (1, pk) -> + Pbrt.Decoder.unexpected_payload "Message(instructions), field(1)" pk + | Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind + done; + ({ + operations = v.operations; + } : instructions) + +[@@@ocaml.warning "-27-30-39"] + +(** {2 Protobuf YoJson Encoding} *) + +let rec encode_json_patch_copy (v:patch_copy) = + let assoc = [] in + let assoc = ("start", Pbrt_yojson.make_string (Int64.to_string v.start)) :: assoc in + let assoc = ("end", Pbrt_yojson.make_string (Int64.to_string v.end_)) :: assoc in + `Assoc assoc + +let rec encode_json_patch_insert (v:patch_insert) = + let assoc = [] in + let assoc = ("rawBytes", Pbrt_yojson.make_bytes v.raw_bytes) :: assoc in + `Assoc assoc + +let rec encode_json_patch_op (v:patch_op) = + begin match v with + | Copy_op v -> `Assoc [("copyOp", encode_json_patch_copy v)] + | Insert_op v -> `Assoc [("insertOp", encode_json_patch_insert v)] + end + +and encode_json_patch (v:patch) = + let assoc = [] in + let assoc = match v.op with + | Some (Copy_op v) -> + ("copyOp", encode_json_patch_copy v) :: assoc + | Some (Insert_op v) -> + ("insertOp", encode_json_patch_insert v) :: assoc + | None -> assoc + in (* match v.op *) + let assoc = ("id", Pbrt_yojson.make_string (Int64.to_string v.id)) :: assoc in + `Assoc assoc + +let rec encode_json_instructions (v:instructions) = + let assoc = [] in + let assoc = + let l = v.operations |> List.map encode_json_patch in + ("operations", `List l) :: assoc + in + `Assoc assoc + +[@@@ocaml.warning "-27-30-39"] + +(** {2 JSON Decoding} *) + +let rec decode_json_patch_copy d = + let v = default_patch_copy_mutable () in + let assoc = match d with + | `Assoc assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("start", json_value) -> + v.start <- Pbrt_yojson.int64 json_value "patch_copy" "start" + | ("end", json_value) -> + v.end_ <- Pbrt_yojson.int64 json_value "patch_copy" "end_" + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + start = v.start; + end_ = v.end_; + } : patch_copy) + +let rec decode_json_patch_insert d = + let v = default_patch_insert_mutable () in + let assoc = match d with + | `Assoc assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("rawBytes", json_value) -> + v.raw_bytes <- Pbrt_yojson.bytes json_value "patch_insert" "raw_bytes" + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + raw_bytes = v.raw_bytes; + } : patch_insert) + +let rec decode_json_patch_op json = + let assoc = match json with + | `Assoc assoc -> assoc + | _ -> assert(false) + in + let rec loop = function + | [] -> Pbrt_yojson.E.malformed_variant "patch_op" + | ("copyOp", json_value)::_ -> + (Copy_op ((decode_json_patch_copy json_value)) : patch_op) + | ("insertOp", json_value)::_ -> + (Insert_op ((decode_json_patch_insert json_value)) : patch_op) + + | _ :: tl -> loop tl + in + loop assoc + +and decode_json_patch d = + let v = default_patch_mutable () in + let assoc = match d with + | `Assoc assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("copyOp", json_value) -> + v.op <- Some (Copy_op ((decode_json_patch_copy json_value))) + | ("insertOp", json_value) -> + v.op <- Some (Insert_op ((decode_json_patch_insert json_value))) + | ("id", json_value) -> + v.id <- Pbrt_yojson.int64 json_value "patch" "id" + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + op = v.op; + id = v.id; + } : patch) + +let rec decode_json_instructions d = + let v = default_instructions_mutable () in + let assoc = match d with + | `Assoc assoc -> assoc + | _ -> assert(false) + in + List.iter (function + | ("operations", `List l) -> begin + v.operations <- List.map (function + | json_value -> (decode_json_patch json_value) + ) l; + end + + | (_, _) -> () (*Unknown fields are ignored*) + ) assoc; + ({ + operations = v.operations; + } : instructions) diff --git a/src/examples/oneof.mli.expected b/src/examples/oneof.mli.expected new file mode 100644 index 00000000..b7037350 --- /dev/null +++ b/src/examples/oneof.mli.expected @@ -0,0 +1,155 @@ + +(** Code for oneof.proto *) + +(* generated from "oneof.proto", do not edit *) + + + +(** {2 Types} *) + +type patch_copy = { + start : int64; + end_ : int64; +} + +type patch_insert = { + raw_bytes : bytes; +} + +type patch_op = + | Copy_op of patch_copy + | Insert_op of patch_insert + +and patch = { + op : patch_op option; + id : int64; +} + +type instructions = { + operations : patch list; +} + + +(** {2 Basic values} *) + +val default_patch_copy : + ?start:int64 -> + ?end_:int64 -> + unit -> + patch_copy +(** [default_patch_copy ()] is the default value for type [patch_copy] *) + +val default_patch_insert : + ?raw_bytes:bytes -> + unit -> + patch_insert +(** [default_patch_insert ()] is the default value for type [patch_insert] *) + +val default_patch_op : unit -> patch_op +(** [default_patch_op ()] is the default value for type [patch_op] *) + +val default_patch : + ?op:patch_op option -> + ?id:int64 -> + unit -> + patch +(** [default_patch ()] is the default value for type [patch] *) + +val default_instructions : + ?operations:patch list -> + unit -> + instructions +(** [default_instructions ()] is the default value for type [instructions] *) + + +(** {2 Formatters} *) + +val pp_patch_copy : Format.formatter -> patch_copy -> unit +(** [pp_patch_copy v] formats v *) + +val pp_patch_insert : Format.formatter -> patch_insert -> unit +(** [pp_patch_insert v] formats v *) + +val pp_patch_op : Format.formatter -> patch_op -> unit +(** [pp_patch_op v] formats v *) + +val pp_patch : Format.formatter -> patch -> unit +(** [pp_patch v] formats v *) + +val pp_instructions : Format.formatter -> instructions -> unit +(** [pp_instructions v] formats v *) + + +(** {2 Protobuf Encoding} *) + +val encode_pb_patch_copy : patch_copy -> Pbrt.Encoder.t -> unit +(** [encode_pb_patch_copy v encoder] encodes [v] with the given [encoder] *) + +val encode_pb_patch_insert : patch_insert -> Pbrt.Encoder.t -> unit +(** [encode_pb_patch_insert v encoder] encodes [v] with the given [encoder] *) + +val encode_pb_patch_op : patch_op -> Pbrt.Encoder.t -> unit +(** [encode_pb_patch_op v encoder] encodes [v] with the given [encoder] *) + +val encode_pb_patch : patch -> Pbrt.Encoder.t -> unit +(** [encode_pb_patch v encoder] encodes [v] with the given [encoder] *) + +val encode_pb_instructions : instructions -> Pbrt.Encoder.t -> unit +(** [encode_pb_instructions v encoder] encodes [v] with the given [encoder] *) + + +(** {2 Protobuf Decoding} *) + +val decode_pb_patch_copy : Pbrt.Decoder.t -> patch_copy +(** [decode_pb_patch_copy decoder] decodes a [patch_copy] binary value from [decoder] *) + +val decode_pb_patch_insert : Pbrt.Decoder.t -> patch_insert +(** [decode_pb_patch_insert decoder] decodes a [patch_insert] binary value from [decoder] *) + +val decode_pb_patch_op : Pbrt.Decoder.t -> patch_op +(** [decode_pb_patch_op decoder] decodes a [patch_op] binary value from [decoder] *) + +val decode_pb_patch : Pbrt.Decoder.t -> patch +(** [decode_pb_patch decoder] decodes a [patch] binary value from [decoder] *) + +val decode_pb_instructions : Pbrt.Decoder.t -> instructions +(** [decode_pb_instructions decoder] decodes a [instructions] binary value from [decoder] *) + + +(** {2 Protobuf YoJson Encoding} *) + +val encode_json_patch_copy : patch_copy -> Yojson.Basic.t +(** [encode_json_patch_copy v encoder] encodes [v] to to json *) + +val encode_json_patch_insert : patch_insert -> Yojson.Basic.t +(** [encode_json_patch_insert v encoder] encodes [v] to to json *) + +val encode_json_patch_op : patch_op -> Yojson.Basic.t +(** [encode_json_patch_op v encoder] encodes [v] to to json *) + +val encode_json_patch : patch -> Yojson.Basic.t +(** [encode_json_patch v encoder] encodes [v] to to json *) + +val encode_json_instructions : instructions -> Yojson.Basic.t +(** [encode_json_instructions v encoder] encodes [v] to to json *) + + +(** {2 JSON Decoding} *) + +val decode_json_patch_copy : Yojson.Basic.t -> patch_copy +(** [decode_json_patch_copy decoder] decodes a [patch_copy] value from [decoder] *) + +val decode_json_patch_insert : Yojson.Basic.t -> patch_insert +(** [decode_json_patch_insert decoder] decodes a [patch_insert] value from [decoder] *) + +val decode_json_patch_op : Yojson.Basic.t -> patch_op +(** [decode_json_patch_op decoder] decodes a [patch_op] value from [decoder] *) + +val decode_json_patch : Yojson.Basic.t -> patch +(** [decode_json_patch decoder] decodes a [patch] value from [decoder] *) + +val decode_json_instructions : Yojson.Basic.t -> instructions +(** [decode_json_instructions decoder] decodes a [instructions] value from [decoder] *) + + +(** {2 Services} *) diff --git a/src/examples/oneof.proto b/src/examples/oneof.proto new file mode 100644 index 00000000..0489c704 --- /dev/null +++ b/src/examples/oneof.proto @@ -0,0 +1,22 @@ +syntax="proto3"; + +message Patch { + message Copy { + int64 start =1; + int64 end=2; + } + + message Insert { + bytes raw_bytes=1; + + } + oneof op { + Copy copy_op=3; + Insert insert_op=4; + } + int64 id = 5; +} + +message Instructions { + repeated Patch operations=1; +} diff --git a/src/tests/expectation/option_processing.ml.expected b/src/tests/expectation/option_processing.ml.expected index d36a0f95..3e1a3439 100644 --- a/src/tests/expectation/option_processing.ml.expected +++ b/src/tests/expectation/option_processing.ml.expected @@ -21,7 +21,7 @@ and person = { name : string; home : person_location option; picture : bytes; - id : person_id; + id : person_id option; } let rec default_payment_system () = (Cash:payment_system) @@ -42,7 +42,7 @@ and default_person ?name:((name:string) = "") ?home:((home:person_location option) = None) ?picture:((picture:bytes) = Bytes.create 0) - ?id:((id:person_id) = X ("")) + ?id:((id:person_id option) = None) () : person = { id; email;