code: private MessageElement readMessage(String documentation) {
      String name = readName();
      MessageElement.Builder builder = MessageElement.builder()
          .name(name)
          .qualifiedName(prefix + name)
          .documentation(documentation);
  
      String previousPrefix = prefix;
      prefix = prefix + name + ".";
  
      if (readChar() != '{') throw unexpected("expected '{'");
      while (true) {
        String nestedDocumentation = readDocumentation();
        if (peekChar() == '}') {
          pos++;
          break;
        }
        Object declared = readDeclaration(nestedDocumentation, Context.MESSAGE);
        if (declared instanceof FieldElement) {
          builder.addField((FieldElement) declared);
        } else if (declared instanceof OneOfElement) {
          builder.addOneOf((OneOfElement) declared);
        } else if (declared instanceof TypeElement) {
          builder.addType((TypeElement) declared);
        } else if (declared instanceof ExtensionsElement) {
          builder.addExtensions((ExtensionsElement) declared);
        } else if (declared instanceof OptionElement) {
          builder.addOption((OptionElement) declared);
        } else if (declared instanceof ExtendElement) {
          // Extend declarations always add in a global scope regardless of nesting.
          fileBuilder.addExtendDeclaration((ExtendElement) declared);
        }
      }
      prefix = previousPrefix;
  
      return builder.build();
    }
docs: Reads a message declaration.