syntax = "proto2";
package protobuf_mutator.xml;

// Simplified definition of XML formant according https://www.w3.org/TR/xml/
// Not all features are implemented and some rules are flattened.

// There are no required fields to allow backward compatibility with older
// corpus.

// document ::= prolog element Misc*
// prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
// XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
// doctypedecl ::=
//    '<!DOCTYPE' S Name (S ExternalID)? S? ('[' intSubset ']' S?)? '>'
message Document {
  // XMLDecl
  optional string version = 1;
  optional string encoding = 2;
  optional bool standalone = 3;

  repeated Misk misk1 = 4;
  optional DoctypeDecl doctype = 5;
  optional Element element = 6;
  repeated Misk misk2 = 7;
}

message DoctypeDecl {
  optional string name = 1;
  optional string external_id = 2;
  optional string int_subset = 3;
  repeated Misk misk = 4;
}

message Misk {
  oneof _ {
    Pi pi = 1;
    string comment = 2;
  }
}

// element ::= EmptyElemTag | STag content ETag
message Element {
  optional Tag tag = 1;
  // Use EmptyElemTag tag if missing, or STag and ETag otherwise.
  repeated Content content = 2;
}

// EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
// STag ::= '<' Name (S Attribute)* S? '>'
// ETag ::= '</' Name S? '>'
message Tag {
  optional string name = 1;
  repeated Attribute attribute = 2;
}

message Reference {
  optional string name = 1;
  optional bool entry = 2;
}

message Pi {
  optional string target = 1;
  optional string data = 2;
}

// content ::=
//    CharData? ((element | Reference | CDSect | PI | Comment) CharData?)*
message Content {
  oneof _ {
    string char_data = 1;
    Element element = 2;
    Reference reference = 3;
    string cdsect = 4;
    Misk misk = 5;
  }
}

// Attribute ::=  Name Eq AttValue
message Attribute {
  optional string name = 1;
  optional string value = 2;
}

message Input {
  optional Document document = 1;

  // Option will be sent into libxml2 parser.
  // TODO(vitalybuka): Use proto extension. Options is libxml2 specific,
  // other libs may need different data. At the moment mutator does not support
  // extensions.
  optional uint32 options = 2;
}
