package ocaml-protoc
Pure OCaml compiler for .proto files
Install
Dune Dependency
Authors
Maintainers
Sources
ocaml-protoc-3.1.1.tbz
sha256=c5657fcbfcbaea361beb847f72b8a6a6f36ce9e773bf285b278a0da75f988fbc
sha512=ea86d04b6293eba48360409049f907fc3e73138ec434b5d1894a2dcdaa0478f6f5a1d13f1ba87c553ddf6806a618525f621d2af862b495ce3426242a3a42e339
doc/src/ocaml-protoc.compiler-lib/pb_codegen_encode_bs.ml.html
Source file pb_codegen_encode_bs.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
module Ot = Pb_codegen_ocaml_type module F = Pb_codegen_formatting let sp = Pb_codegen_util.sp let unsupported json_label = failwith (sp "Unsupported field type for field: %s" json_label) let unsupported2 json_label x y = failwith (sp "Unsupported 2 field type for field: %s (%s, %s)" json_label (Pb_codegen_util.string_of_basic_type x) (Pb_codegen_util.string_of_payload_kind y false)) let setter_of_basic_type json_label basic_type pk = match basic_type, pk with (* String *) | Ot.Bt_string, _ -> "string", None (* Float *) | Ot.Bt_float, Ot.Pk_bits32 -> "number", None | Ot.Bt_float, Ot.Pk_bits64 -> "string", Some "Js.Float.toString" (* Int32 *) | Ot.Bt_int32, _ -> "number", Some "Int32.to_float" | Ot.Bt_uint32, _ -> "number", Some "Int32.to_float" (* Int64 *) | Ot.Bt_int64, Ot.Pk_varint _ | Ot.Bt_int64, Ot.Pk_bits64 | Ot.Bt_uint64, Ot.Pk_varint _ | Ot.Bt_uint64, Ot.Pk_bits64 -> "string", Some "Int64.to_string" (* 64 bit integer are always encoded as string since only support up to 51 bits integer. An improvement could be to check for value > 2^51 and use int *) (* int *) | Ot.Bt_int, Ot.Pk_bits32 -> "number", Some "float_of_int" | Ot.Bt_int, Ot.Pk_varint _ | Ot.Bt_int, Ot.Pk_bits64 -> "string", Some "string_of_int" (* bool *) | Ot.Bt_bool, Ot.Pk_varint _ -> "boolean", None (* bytes *) | Ot.Bt_bytes, Ot.Pk_bytes -> unsupported json_label | x, y -> unsupported2 json_label x y let gen_field sc var_name json_label field_type pk = (* reusable function for both basic type and wrapped type which * are both based upon basic type *) let basic_type_statement basic_type var_name pk = let setter, map_function = setter_of_basic_type json_label basic_type pk in match map_function with | None -> Printf.sprintf "Js.Dict.set json \"%s\" (Js.Json.%s %s)" json_label setter var_name | Some map_function -> Printf.sprintf "Js.Dict.set json \"%s\" (Js.Json.%s (%s %s))" json_label setter map_function var_name in match field_type, pk with | Ot.Ft_unit, _ -> F.line sc "(* unit type -> encode nothing *)" (* Basic types *) | Ot.Ft_basic_type basic_type, _ -> let statement = basic_type_statement basic_type var_name pk in F.linep sc "%s;" statement (* User defined *) | Ot.Ft_user_defined_type udt, _ -> let { Ot.udt_type; _ } = udt in let f_name = let function_prefix = "encode" in Pb_codegen_util.function_name_of_user_defined ~function_prefix udt in (match udt_type with | `Message -> F.linep sc "begin (* %s field *)" json_label; F.sub_scope sc (fun sc -> F.linep sc "let json' = %s %s in" f_name var_name; F.linep sc "Js.Dict.set json \"%s\" (Js.Json.object_ json');" json_label); F.line sc "end;" | `Enum -> F.linep sc "Js.Dict.set json \"%s\" (Js.Json.string (%s %s));" json_label f_name var_name) | Ot.Ft_wrapper_type wrapper_type, _ -> let { Ot.wt_type; Ot.wt_pk } = wrapper_type in F.line sc "begin"; F.sub_scope sc (fun sc -> F.linep sc "match %s with" var_name; F.linep sc "| None -> Js.Dict.set json \"%s\" Js.Json.null" json_label; let statement = basic_type_statement wt_type "__x__" wt_pk in F.linep sc "| Some __x__ -> %s" statement); F.line sc "end;" let gen_rft_nolabel sc var_name rf_label (field_type, _, pk) = let json_label = Pb_codegen_util.camel_case_of_label rf_label in gen_field sc var_name json_label field_type pk let gen_rft_optional sc var_name rf_label (field_type, _, pk, _) = F.linep sc "begin match %s with" var_name; F.line sc "| None -> ()"; F.line sc "| Some v ->"; F.sub_scope sc (fun sc -> let json_label = Pb_codegen_util.camel_case_of_label rf_label in gen_field sc "v" json_label field_type pk); F.line sc "end;" let gen_rft_repeated sc var_name rf_label repeated_field = let repeated_type, field_type, _, pk, _ = repeated_field in (match repeated_type with | Ot.Rt_list -> () | Ot.Rt_repeated_field -> sp "Pbrt.Repeated_field is not supported with JSON (field: %s)" rf_label |> failwith); let json_label = Pb_codegen_util.camel_case_of_label rf_label in F.linep sc "begin match %s with" var_name; F.line sc "| [] -> ()"; F.linep sc "| __x__ -> (* %s *)" json_label; F.sub_scope sc (fun sc -> match field_type, pk with | Ot.Ft_unit, _ -> unsupported json_label | Ot.Ft_basic_type basic_type, _ -> let setter, map_function = setter_of_basic_type json_label basic_type pk in (match map_function with | None -> F.linep sc "let a = __x__ |> Array.of_list |> Array.map Js.Json.%s in" setter | Some map_function -> F.line sc @@ sp ("let a = __x__ |> List.map %s |> Array.of_list " ^^ "|> Array.map Js.Json.%s in") map_function setter); F.linep sc "Js.Dict.set json \"%s\" (Js.Json.array a);" json_label (* User defined *) | Ot.Ft_user_defined_type udt, Ot.Pk_bytes -> let f_name = let function_prefix = "encode" in Pb_codegen_util.function_name_of_user_defined ~function_prefix udt in F.linep sc "let (%s':Js.Json.t) =" rf_label; F.sub_scope sc (fun sc -> F.line sc "__x__"; F.line sc "|> Array.of_list"; F.linep sc "|> Array.map (fun v ->"; F.sub_scope sc (fun sc -> F.linep sc "v |> %s |> Js.Json.object_" f_name); F.line sc ")"; F.line sc "|> Js.Json.array"); F.line sc "in"; F.linep sc "Js.Dict.set json \"%s\" %s'" json_label rf_label | _ -> unsupported json_label); F.linep sc "end;" let gen_rft_variant sc var_name rf_label { Ot.v_constructors; _ } = F.linep sc "begin match %s with" var_name; F.sub_scope sc (fun sc -> List.iter (fun { Ot.vc_constructor; vc_field_type; vc_payload_kind; _ } -> let var_name = "v" in let json_label = Pb_codegen_util.camel_case_of_constructor vc_constructor in F.linep sc "| %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); F.linep sc "end; (* match v.%s *)" rf_label let gen_record ?and_ { Ot.r_name; r_fields } sc = let rn = r_name in F.linep sc "%s encode_%s (v:%s) = " (Pb_codegen_util.let_decl_of_and and_) rn rn; F.sub_scope sc (fun sc -> F.line sc "let json = Js.Dict.empty () in"; List.iter (fun record_field -> let { Ot.rf_label; rf_field_type; _ } = record_field in let var_name = sp "v.%s" rf_label in match rf_field_type with | Ot.Rft_nolabel nolabel_field -> gen_rft_nolabel sc var_name rf_label nolabel_field | Ot.Rft_repeated repeated_field -> gen_rft_repeated sc var_name rf_label repeated_field | Ot.Rft_variant variant_field -> gen_rft_variant sc var_name rf_label variant_field | Ot.Rft_optional optional_field -> gen_rft_optional sc var_name rf_label optional_field | Ot.Rft_required _ -> Printf.eprintf "Only proto3 syntax supported in JSON encoding"; exit 1 | Ot.Rft_associative _ -> Printf.eprintf "Map field are not currently supported for JSON"; exit 1) r_fields (* List.iter *); F.line sc "json") let gen_variant ?and_ { Ot.v_name; v_constructors } sc = let process_v_constructor sc v_constructor = let { Ot.vc_constructor; Ot.vc_field_type; Ot.vc_payload_kind; _ } = v_constructor in let json_label = Pb_codegen_util.camel_case_of_constructor vc_constructor in match vc_field_type with | Ot.Vct_nullary -> F.linep sc "| %s ->" vc_constructor; F.linep sc " Js.Dict.set json \"%s\" Js.Json.null" json_label | Ot.Vct_non_nullary_constructor field_type -> F.linep sc "| %s v ->" vc_constructor; F.sub_scope sc (fun sc -> gen_field sc "v" json_label field_type vc_payload_kind) in F.linep sc "%s encode_%s (v:%s) = " (Pb_codegen_util.let_decl_of_and and_) v_name v_name; F.sub_scope sc (fun sc -> F.line sc "let json = Js.Dict.empty () in"; F.line sc "begin match v with"; List.iter (process_v_constructor sc) v_constructors; F.line sc "end;"; F.line sc "json") let gen_const_variant ?and_ { Ot.cv_name; Ot.cv_constructors } sc = F.linep sc "%s encode_%s (v:%s) : string = " (Pb_codegen_util.let_decl_of_and and_) cv_name cv_name; F.sub_scope sc (fun sc -> F.line sc "match v with"; List.iter (fun { Ot.cvc_name; cvc_string_value; _ } -> F.linep sc "| %s -> \"%s\"" cvc_name cvc_string_value) cv_constructors) let gen_unit ?and_ { Ot.er_name } sc = let rn = er_name in F.linep sc "%s encode_%s (_v:%s) = " (Pb_codegen_util.let_decl_of_and and_) rn rn; F.line sc "Js.Json.null" let gen_struct ?and_ t sc : bool = 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 v -> gen_unit ?and_ v 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 encode_%s : %s -> Js.Json.t Js.Dict.t" type_name type_name; F.linep sc ("(** [encode_%s v dict] encodes [v] int the " ^^ "given JSON [dict] *)") type_name in match spec with | Ot.Record { Ot.r_name; _ } -> f r_name; true | Ot.Variant v -> f v.Ot.v_name; true | Ot.Const_variant { Ot.cv_name; _ } -> F.linep sc "val encode_%s : %s -> string" cv_name cv_name; F.linep sc "(** [encode_%s v] returns JSON string *)" cv_name; true | Ot.Unit { Ot.er_name } -> F.linep sc "val encode_%s : %s -> Js.Json.t" er_name er_name; F.linep sc "(** [encode_%s v] returns JSON null *)" er_name; true let ocamldoc_title = "Protobuf JSON Encoding" let requires_mutable_records = false 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)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>