def text_fd_to_metric_families(fd):
name = '<STR_LIT>'<EOL>documentation = '<STR_LIT>'<EOL>typ = '<STR_LIT>'<EOL>samples = []<EOL>allowed_names = []<EOL>def build_metric(name, documentation, typ, samples):<EOL><INDENT>if typ == '<STR_LIT>':<EOL><INDENT>if name.endswith('<STR_LIT>'):<EOL><INDENT>name = name[:-<NUM_LIT:6>]<EOL><DEDENT>else:<EOL><INDENT>new_samples = []<EOL>for s in samples:<EOL><INDENT>new_samples.append(Sample(s[<NUM_LIT:0>] + '<STR_LIT>', *s[<NUM_LIT:1>:]))<EOL>samples = new_samples<EOL><DEDENT><DEDENT><DEDENT>metric = Metric(name, documentation, typ)<EOL>metric.samples = samples<EOL>return metric<EOL><DEDENT>for line in fd:<EOL><INDENT>line = line.strip()<EOL>if line.startswith('<STR_LIT:#>'):<EOL><INDENT>parts = line.split(None, <NUM_LIT:3>)<EOL>if len(parts) < <NUM_LIT:2>:<EOL><INDENT>continue<EOL><DEDENT>if parts[<NUM_LIT:1>] == '<STR_LIT>':<EOL><INDENT>if parts[<NUM_LIT:2>] != name:<EOL><INDENT>if name != '<STR_LIT>':<EOL><INDENT>yield build_metric(name, documentation, typ, samples)<EOL><DEDENT>name = parts[<NUM_LIT:2>]<EOL>typ = '<STR_LIT>'<EOL>samples = []<EOL>allowed_names = [parts[<NUM_LIT:2>]]<EOL><DEDENT>if len(parts) == <NUM_LIT:4>:<EOL><INDENT>documentation = _replace_help_escaping(parts[<NUM_LIT:3>])<EOL><DEDENT>else:<EOL><INDENT>documentation = '<STR_LIT>'<EOL><DEDENT><DEDENT>elif parts[<NUM_LIT:1>] == '<STR_LIT>':<EOL><INDENT>if parts[<NUM_LIT:2>] != name:<EOL><INDENT>if name != '<STR_LIT>':<EOL><INDENT>yield build_metric(name, documentation, typ, samples)<EOL><DEDENT>name = parts[<NUM_LIT:2>]<EOL>documentation = '<STR_LIT>'<EOL>samples = []<EOL><DEDENT>typ = parts[<NUM_LIT:3>]<EOL>allowed_names = {<EOL>'<STR_LIT>': ['<STR_LIT>'],<EOL>'<STR_LIT>': ['<STR_LIT>'],<EOL>'<STR_LIT>': ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>'],<EOL>'<STR_LIT>': ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>'],<EOL>}.get(typ, ['<STR_LIT>'])<EOL>allowed_names = [name + n for n in allowed_names]<EOL><DEDENT>else:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>elif line == '<STR_LIT>':<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>sample = _parse_sample(line)<EOL>if sample.name not in allowed_names:<EOL><INDENT>if name != '<STR_LIT>':<EOL><INDENT>yield build_metric(name, documentation, typ, samples)<EOL><DEDENT>name = '<STR_LIT>'<EOL>documentation = '<STR_LIT>'<EOL>typ = '<STR_LIT>'<EOL>samples = []<EOL>allowed_names = []<EOL>yield build_metric(sample[<NUM_LIT:0>], documentation, typ, [sample])<EOL><DEDENT>else:<EOL><INDENT>samples.append(sample)<EOL><DEDENT><DEDENT><DEDENT>if name != '<STR_LIT>':<EOL><INDENT>yield build_metric(name, documentation, typ, samples)<EOL><DEDENT>
Parse Prometheus text format from a file descriptor.

    This is a laxer parser than the main Go parser,
    so successful parsing does not imply that the parsed
    text meets the specification.

    Yields Metric's.