val size32_serverName_cases (x: LP.dsum_known_key serverName_sum)
    : LSZ.size32 (serialize_serverName_cases x)
val size32_serverName_cases (x: LP.dsum_known_key serverName_sum)
    : LSZ.size32 (serialize_serverName_cases x)
let size32_serverName_cases (x:LP.dsum_known_key serverName_sum)
  : LSZ.size32 (serialize_serverName_cases x) =
  match x with
  | Host_name -> [@inline_let] let u : LSZ.size32 (serialize_serverName_cases Host_name) = hostName_size32 in u
  | _ -> LSZ.size32_false
module MiTLS.Parsers.ServerName

(* This file has been automatically generated by EverParse. *)
open FStar.Bytes
module U8 = FStar.UInt8
module U16 = FStar.UInt16
module U32 = FStar.UInt32
module U64 = FStar.UInt64
module LP = LowParse.Spec
module LT = LowParse.TacLib
module LS = LowParse.SLow
module LSZ = LowParse.SLow
module LPI = LowParse.Spec.AllIntegers
module LL = LowParse.Low
module L = FStar.List.Tot
module B = LowStar.Buffer
module BY = FStar.Bytes
module HS = FStar.HyperStack
module HST = FStar.HyperStack.ST

#reset-options "--using_facts_from '* -FStar.Tactics -FStar.Reflection' --z3rlimit 16 --z3cliopt smt.arith.nl=false --max_fuel 2 --max_ifuel 2"

friend MiTLS.Parsers.NameType

// Need high Z3 limits for large sum types
#set-options "--z3rlimit 60"

inline_for_extraction unfold let known_nameType_as_enum_key
  (x: nameType { norm [delta; zeta; iota; primops] (LP.list_mem x (LP.list_map fst nameType_enum)) == true })
  : LP.enum_key nameType_enum =
  [@inline_let] let _ = norm_spec [delta; zeta; iota; primops] (LP.list_mem x (LP.list_map fst nameType_enum)) in x

inline_for_extraction let unknown_nameType_as_enum_key (r:nameType_repr) : Pure (LP.unknown_enum_repr nameType_enum)
  (requires known_nameType_repr r == false) (ensures fun _ -> True) =
  [@inline_let] let _ = assert_norm(LP.list_mem r (LP.list_map snd nameType_enum) == known_nameType_repr r) in r

inline_for_extraction let unknown_enum_repr_nameType_as_repr (r:LP.unknown_enum_repr nameType_enum) : Pure nameType_repr
  (requires True) (ensures fun r -> known_nameType_repr r == false) =
  [@inline_let] let _ = assert_norm(LP.list_mem r (LP.list_map snd nameType_enum) == known_nameType_repr r) in r

inline_for_extraction let key_of_serverName (x:serverName) : LP.maybe_enum_key nameType_enum =
  match x with
  | Sni_host_name _ -> LP.Known (known_nameType_as_enum_key Host_name)
  | Sni_Unknown_nameType v _ -> LP.Unknown (unknown_nameType_as_enum_key v)

inline_for_extraction let serverName_case_of_nameType (x:nameType) : Type0 =
  match x with
  | Host_name -> hostName
  | Unknown_nameType _ -> squash False

unfold inline_for_extraction let serverName_value_type (x:LP.maybe_enum_key nameType_enum) =
  LP.dsum_type_of_tag' nameType_enum serverName_case_of_nameType unknownName x

unfold inline_for_extraction let serverName_refine (k:LP.maybe_enum_key nameType_enum) (x:serverName)
  : Pure (LP.refine_with_tag key_of_serverName k)
  (requires key_of_serverName x == k) (ensures fun y -> y == x) =
  [@inline_let] let _ = norm_spec [delta; iota; zeta] (key_of_serverName x) in x

unfold inline_for_extraction let serverName_type_of_known_case (k: LP.enum_key nameType_enum)
  (x:nameType) (q: squash ((k <: nameType) == x))
  (#x' : LP.maybe_enum_key nameType_enum) (y: serverName_value_type x')
  : Pure (norm [delta_only [(`%serverName_case_of_nameType)]; iota] (serverName_case_of_nameType x))
  (requires (LP.Known k == x')) (ensures (fun y' -> y' == y)) =
  [@inline_let] let _ = norm_spec [delta_only [(`%serverName_case_of_nameType)]; iota] (serverName_case_of_nameType k) in y

unfold inline_for_extraction let serverName_known_case (k: LP.enum_key nameType_enum)
  (x: nameType) (y: norm [delta_only [(`%serverName_case_of_nameType)]; iota] (serverName_case_of_nameType x))
  : Pure (serverName_case_of_nameType k) (requires (k == x)) (ensures (fun y' -> y' == y)) =
  [@inline_let] let _ = norm_spec [delta_only [(`%serverName_case_of_nameType)] ; iota] (serverName_case_of_nameType x) in y

inline_for_extraction let synth_known_serverName_cases (k:LP.enum_key nameType_enum)
  (y:serverName_value_type (LP.Known k)) : LP.refine_with_tag key_of_serverName (LP.Known k) =
  match k with
  | Host_name ->
    [@inline_let] let x : serverName = Sni_host_name (serverName_type_of_known_case k Host_name () y) in
    [@inline_let] let _ = assert_norm (key_of_serverName x == LP.Known Host_name) in
    serverName_refine (LP.Known Host_name) x

inline_for_extraction let synth_serverName_cases (x:LP.maybe_enum_key nameType_enum)
  (y:serverName_value_type x) : LP.refine_with_tag key_of_serverName x =
  match x with
  | LP.Unknown v ->
    [@inline_let] let x : serverName = Sni_Unknown_nameType (unknown_enum_repr_nameType_as_repr v) y in
    [@inline_let] let _ = assert_norm (key_of_serverName x == LP.Unknown v) in
    serverName_refine (LP.Unknown v) x
  | LP.Known k -> synth_known_serverName_cases k y

unfold inline_for_extraction let from_serverName_case_of_nameType (#x':nameType) (x:nameType)
  (y: norm [delta_only [(`%serverName_case_of_nameType)]; iota] (serverName_case_of_nameType x))
  : Pure (serverName_case_of_nameType x') (requires (x == x')) (ensures (fun y' -> y' == y)) =
  [@inline_let] let _ = norm_spec [delta_only [(`%serverName_case_of_nameType)] ; iota] (serverName_case_of_nameType x) in y

let synth_serverName_cases_recip_pre (k:LP.maybe_enum_key nameType_enum)
  (x:LP.refine_with_tag key_of_serverName k) : GTot bool =
  match k with
  | LP.Known Host_name -> Sni_host_name? x
  | LP.Known _ -> false
  | LP.Unknown _ -> Sni_Unknown_nameType? x

let synth_serverName_cases_recip_pre_intro' (x: serverName)
  : Lemma (synth_serverName_cases_recip_pre (key_of_serverName x) x) = ()

let synth_serverName_cases_recip_pre_intro (k:LP.maybe_enum_key nameType_enum)
  (x:LP.refine_with_tag key_of_serverName k)
  : Lemma (synth_serverName_cases_recip_pre k x == true) =
  synth_serverName_cases_recip_pre_intro' x

inline_for_extraction let synth_serverName_cases_recip (k:LP.maybe_enum_key nameType_enum)
  (x:LP.refine_with_tag key_of_serverName k) : (serverName_value_type k) =
  match k with
  | LP.Unknown z ->
    [@inline_let] let _ = synth_serverName_cases_recip_pre_intro (LP.Unknown z) x in
    (match x with Sni_Unknown_nameType _ y ->  (y <: serverName_value_type k))
  | LP.Known k' ->
    match k' with
    | Host_name -> [@inline_let] let _ = synth_serverName_cases_recip_pre_intro (LP.Known Host_name) x in
      (match x with Sni_host_name y -> serverName_known_case k' Host_name y)
   | _ -> [@inline_let] let _ = synth_serverName_cases_recip_pre_intro (LP.Known k') in false_elim ()

inline_for_extraction let serverName_sum : LP.dsum = LP.make_dsum' nameType_enum key_of_serverName
  serverName_case_of_nameType unknownName synth_serverName_cases synth_serverName_cases_recip
  (_ by (LP.make_dsum_synth_case_recip_synth_case_known_tac ()))
  (_ by (LP.make_dsum_synth_case_recip_synth_case_unknown_tac ()))
  (_ by (LP.synth_case_synth_case_recip_tac ()))

noextract let parse_serverName_cases (x:LP.dsum_known_key serverName_sum)
  : k:LP.parser_kind & LP.parser k (serverName_case_of_nameType x) =
  match x with
  | Host_name -> [@inline_let] let u : (k: LP.parser_kind & LP.parser k (serverName_case_of_nameType Host_name)) = (| _, hostName_parser |) in u
  | _ -> (| _, LP.parse_false |)

noextract let serialize_serverName_cases (x:LP.dsum_known_key serverName_sum)
  : LP.serializer (dsnd (parse_serverName_cases x)) =
  match x with
  | Host_name -> [@inline_let] let u : LP.serializer (dsnd (parse_serverName_cases Host_name)) = hostName_serializer in u
  | _ -> LP.serialize_false

inline_for_extraction noextract let parse32_serverName_cases (x:LP.dsum_known_key serverName_sum)
  : LS.parser32 (dsnd (parse_serverName_cases x)) =
  match x with
  | Host_name -> [@inline_let] let u : LS.parser32 (dsnd (parse_serverName_cases Host_name)) = hostName_parser32 in u
  | _ -> LS.parse32_false

inline_for_extraction noextract let serialize32_serverName_cases (x:LP.dsum_known_key serverName_sum)
  : LS.serializer32 (serialize_serverName_cases x) =
  match x with
  | Host_name -> [@inline_let] let u : LS.serializer32 (serialize_serverName_cases Host_name) = hostName_serializer32 in u
  | _ -> LS.serialize32_false
/
prims.fst.checked MiTLS.Parsers.NameType.fst.checked LowStar.Buffer.fst.checked LowParse.TacLib.fst.checked LowParse.Spec.AllIntegers.fst.checked LowParse.Spec.fst.checked LowParse.SLow.fst.checked LowParse.Low.fst.checked FStar.UInt8.fsti.checked FStar.UInt64.fsti.checked FStar.UInt32.fsti.checked FStar.UInt16.fsti.checked FStar.Tactics.Effect.fsti.checked FStar.Seq.fst.checked FStar.Pervasives.fsti.checked FStar.List.Tot.fst.checked FStar.HyperStack.ST.fsti.checked FStar.HyperStack.fst.checked FStar.Bytes.fsti.checked
MiTLS.Parsers.ServerName.fst
x: LowParse.Spec.Sum.dsum_known_key MiTLS.Parsers.ServerName.serverName_sum
  -> LowParse.SLow.Base.size32 (MiTLS.Parsers.ServerName.serialize_serverName_cases x)
LowParse.Spec.Sum.dsum_known_key MiTLS.Parsers.ServerName.serverName_sum LowParse.SLow.Base.size32 Prims.__proj__Mkdtuple2__item___1 LowParse.Spec.Base.parser_kind LowParse.Spec.Base.parser MiTLS.Parsers.ServerName.serverName_case_of_nameType MiTLS.Parsers.NameType.Host_name MiTLS.Parsers.ServerName.parse_serverName_cases FStar.Pervasives.dsnd MiTLS.Parsers.ServerName.serialize_serverName_cases MiTLS.Parsers.HostName.hostName_size32 MiTLS.Parsers.NameType.nameType LowParse.SLow.Combinators.size32_false
let size32_serverName_cases (x: LP.dsum_known_key serverName_sum)
    : LSZ.size32 (serialize_serverName_cases x) =
  
match x with
| Host_name ->
  [@@ inline_let ]let u:LSZ.size32 (serialize_serverName_cases Host_name) = hostName_size32 in
  u
| _ -> LSZ.size32_false