Sync with 5.2.0
[deliverable/titan.core.git] / core / XER.hh
CommitLineData
970ed795
EL
1///////////////////////////////////////////////////////////////////////////////
2// Copyright (c) 2000-2014 Ericsson Telecom AB
3// All rights reserved. This program and the accompanying materials
4// are made available under the terms of the Eclipse Public License v1.0
5// which accompanies this distribution, and is available at
6// http://www.eclipse.org/legal/epl-v10.html
7///////////////////////////////////////////////////////////////////////////////
8#ifndef XER_HH_
9#define XER_HH_
10
11#include "Types.h"
12#include "Encdec.hh"
13#include <stddef.h> // for size_t
14#include <string.h> // strncmp for the inline function
15
16class XmlReaderWrap;
17
18class Base_Type;
af710487 19#ifdef TITAN_RUNTIME_2
20class Record_Of_Type;
21class Erroneous_descriptor_t;
22#endif
970ed795
EL
23class TTCN_Module;
24
25/** @defgroup XER XER codec
26 * @{
27 *
28 * @brief ASN.1 XML Encoding Rules, ITU-T Rec X.693 and amd1
29 */
30
31/** XER flags for various uses.
32 *
33 * Low values specify the XML encoding variant (Basic, Canonical, Extended)
34 * Other bits have dual uses:
35 * - set in XERdescriptor_t::xer_bits, according to XML encoding attributes
36 * - passed in as additional flags in the \c flavor parameter, usually
37 * to XER_encode. These are used when encoding attributes in a parent type
38 * influence the encoding of its components (e.g. EMBED-VALUES on a record
39 * change the encoding of all components).
40 */
41enum XER_flavor {
42 XER_BASIC = 1U << 0, /**< Basic XER with indentation */
43 XER_CANONICAL = 1U << 1, /**< Canonical XER, no indentation */
44 XER_EXTENDED = 1U << 2, /**< Extended XER */
45 DEF_NS_PRESENT = 1U << 3, // 0x08
46 DEF_NS_SQUASHED = 1U << 4, // 0x10
47 XER_MASK = 0x1FU, /**< All the "real" XER flavors plus DEF_NS */
48
49 /* Additional flags, for the parent to pass information to its children
50 * (when the parent affects the child, e.g. LIST) */
51 XER_ESCAPE_ENTITIES = 1U << 5, /**< Escape according to X.680/2002, 11.15.8,
52 used internally by UNIVERSAL_CHARSTRING. */
53 XER_RECOF = 1U << 6, /**< Generating code for the contained type
54 of a record-of/set-of. Only affects BOOLEAN, CHOICE, ENUMERATED and NULL
55 (see Table 5 in X.680 (11/2008) clause 26.5) */
56
57 /* More flags for XERdescriptor_t::xer_bits */
58 ANY_ATTRIBUTES = 1U << 7, // 0xooo80
59 ANY_ELEMENT = 1U << 8, // 0xoo100
60 XER_ATTRIBUTE = 1U << 9, // 0xoo200
61 BASE_64 = 1U << 10, // 0xoo400
62 XER_DECIMAL = 1U << 11, // 0xoo800
63 // DEFAULT-FOR-EMPTY has its own field
64 EMBED_VALUES = 1U << 12, // 0xo1000
65 /** LIST encoding instruction for record-of/set-of. */
66 XER_LIST = 1U << 13, // 0xo2000
67 // NAME is stored in the descriptor
68 // NAMESPACE is folded into the name
69 XER_TEXT = 1U << 14, // 0xo4000
70 UNTAGGED = 1U << 15, // 0xo8000
71 USE_NIL = 1U << 16, // 0x10000
72 USE_NUMBER = 1U << 17, // 0x20000
73 USE_ORDER = 1U << 18, // 0x40000
74 USE_QNAME = 1U << 19, // 0x80000
75 USE_TYPE_ATTR = 1U << 20, // 0x100000, either USE-TYPE or USE-UNION
76 HAS_1UNTAGGED = 1U << 21, // 0x200000 member, and it's character-encodable
77 // another hint to pass down to the children:
78 PARENT_CLOSED = 1U << 22, // 0x400000
79 FORM_UNQUALIFIED=1U << 23, // 0X800000 (qualified is more frequent)
80 XER_TOPLEVEL = 1U << 24, //0X1000000 (toplevel, for decoding)
81 SIMPLE_TYPE = 1U << 25, /*0X2000000 always encode on one line:
82 <foo>content</foo>, never <foo>\ncontent\n</foo> */
83 BXER_EMPTY_ELEM= 1U << 26, /*0X4000000 boolean and enum encode themselves
84 as empty elements in BXER only. This also influences them in record-of */
85 ANY_FROM = 1U << 27, // 0x8000000 anyElement from ... or anyAttributes from ...
86 ANY_EXCEPT = 1U << 28, // 0x10000000 anyElement except ... or anyAttributes except ...
87 EXIT_ON_ERROR = 1U << 29 /* 0x20000000 clean up and exit instead of throwing
88 a decoding error, used on alternatives of a union with USE-UNION */
89};
90
91/** WHITESPACE actions.
92 * Note that WHITESPACE_COLLAPSE includes the effect of WHITESPACE_REPLACE
93 * and the code relies on WHITESPACE_COLLAPSE having the higher value. */
94enum XER_whitespace_action {
95 WHITESPACE_PRESERVE,
96 WHITESPACE_REPLACE,
97 WHITESPACE_COLLAPSE
98};
99
100/// Check that \p f has the canonical flavor.
101inline bool is_canonical(unsigned int f)
102{
103 return (f & XER_CANONICAL) != 0;
104}
105
106inline bool is_exer(unsigned int f)
107{
108 return (f & XER_EXTENDED) != 0;
109}
110
111/** Is this a member of a SEQUENCE OF
112 *
113 * @param f XER flavor
114 * @return \c true if \p contains \c XER_RECOF, \c false otherwise
115 */
116inline bool is_record_of(unsigned int f)
117{
118 return (f & XER_RECOF) != 0;
119}
120
121/** Do list encoding
122 *
123 * This is now hijacked to mean "the enclosing type told us to omit our tag".
124 * Hence the check for USE-NIL too.
125 *
126 * @param f XER flavor
127 * @return \c true if \c XER_EXTENDED and either \c XER_LIST or \c USE_NIL is set.
128 */
129inline bool is_exerlist(unsigned int f)
130{
131 return (f & XER_EXTENDED) && ((f & (XER_LIST|USE_NIL|USE_TYPE_ATTR)) != 0);
132}
133
134/** Descriptor for XER encoding/decoding during runtime.
135 *
136 * This structure contains XER enc/dec information for the runtime.
137 *
138 * There is an instance of this struct for most TTCN3/ASN1 types.
139 * Because TITAN generates type aliases (typedefs) when one type references
140 * another (e.g. "type integer i1" results in "typedef INTEGER i1"),
141 * this struct holds information to distinguish them during encoding.
142 *
143 * Only those encoding instructions need to be recorded which can apply to
144 * scalar types (e.g. BOOLEAN, REAL, etc., usually implemented by classes in core/)
145 * because the same code needs to handle all varieties.
146 *
147 * - ANY-ELEMENT : UFT8String
148 * - BASE64 : OCTET STRING, open type, restricted character string
149 * - DECIMAL : REAL
150 * - NAME : anything (this is already present as \c name)
151 * - NAMESPACE : hmm
152 * - TEXT : INTEGER, enum
153 * - USE-NUMBER : enum
154 * - WHITESPACE : restricted character string
155 *
156 * ANY-ATTRIBUTE, EMBED-VALUES, LIST, USE-TYPE, USE-UNION apply to sequence/choice types;
157 * their effect will be resolved by the compiler.
158 *
159 * Instances of this type are written by the compiler into the generated code,
160 * one for each type. For a TTCN3 type foo_bar, there will be a class
161 * foo__bar and a XERdescriptor_t instance named foo__bar_xer_.
162 *
163 * Each built-in type has a descriptor (e.g. INTEGER_xer_) in the runtime.
164 *
165 * The \a name field contains the closing tag including a newline, e.g.
166 * \c "</INTEGER>\n". This allows for a more efficient output of the tags,
167 * minimizing the number of one-character inserts into the buffer.
168 *
169 * The start tag is written as an 'open angle bracket' character,
170 * followed by the \a name field without its first two characters (\c "</" ).
171 *
172 * In case of the canonical encoding (\c CXER ) there is no indenting,
173 * so the final newline is omitted by reducing the length by one.
174 *
175 * Example:
176 * @code
177 * int Foo::XER_encode(const XERdescriptor_t& p_td,
af710487 178 * TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const {
970ed795
EL
179 * int canon = is_canonical(flavor);
180 * if (!canon) do_indent(p_buf, indent);
181 * // output the start tag
182 * p_buf.put_c('<');
183 * p_buf.put_s((size_t)p_td.namelen-2-canon, (const unsigned char*)p_td.name+2);
184 * // this is not right if Foo has attributes :(
185 * // we'll need to reduce namelen further (or just get rid of this hackery altogether)
186 *
187 * // output actual content
188 * p_buf.put_.....
189 *
190 * // output the closing tag
191 * if (!canon) do_indent(p_buf, indent);
192 * p_buf.put_s((size_t)p_td.namelen-canon, (const unsigned char*)p_td.name);
193 * }
194 * @endcode
195 *
196 * Empty element tag:
197 *
198 * @code
199 * int Foo::XER_encode(const XERdescriptor_t& p_td,
af710487 200 * TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const {
970ed795
EL
201 * int canon = is_canonical(flavor);
202 * if (!canon) do_indent(p_buf, indent);
203 * // output an empty element tag
204 * p_buf.put_c('<');
205 * p_buf.put_s((size_t)p_td.namelen-4, (const unsigned char*)p_td.name+2);
206 * p_buf.put_s(3 - canon, (const unsigned char*)"/>\n");
207 * }
208 * @endcode
209 *
210 * @note We don't generate the XML prolog. This is required for Canonical XER
211 * (X.693 9.1.1) and permitted for Basic-XER (8.2.1).
212 *
213 * @note X.693 amd1 (EXER) 10.3.5 states: If an "ExtendedXMLValue" is empty,
214 * and its associated tags have not been removed by the use of an UNTAGGED
215 * encoding instruction, then the associated preceding and following tags
216 * <b>can (as an encoder's option)</b> be replaced with
217 * an XML empty-element tag (see ITU-T Rec. X.680 | ISO/IEC 8824-1, 16.8).
218 * This is called the associated empty-element tag.
219 *
220 * @note X.693 (XER) 9.1.4 states: (for Canonical XER)
221 * If the XML value notation permits the use of an XML empty-element tag
222 * (see ITU-T Rec. X.680 |ISO/IEC 8824-1, 15.5 and 16.8),
223 * then this empty-element tag @b shall be used.
224 *
225 * @note After editing XERdescriptor_t, make sure to change XER_STRUCT2 here
226 * and generate_code_xerdescriptor() in Type.cc.
227 * */
228struct XERdescriptor_t
229{
230 /** (closing) Tag name, including a newline.
231 * First is for basic and canonical XER, second for EXER */
232 const char *names[2];
233 /** Length of closing tag string (strlen of names[i]) */
234 const unsigned short namelens[2];
235 /** Various EXER flags */
236 const unsigned long xer_bits;
237 /** Whitespace handling */
238 const XER_whitespace_action whitespace;
239 /** value to compare for DEFAULT-FOR-EMPTY */
240 const Base_Type* dfeValue;
241 /** The module to which the type belongs. May be NULL in a descriptor
242 * for a built-in type, e.g. in INTEGER_xer_ */
243 const TTCN_Module* my_module;
244 /** Index into the module's namespace list.
245 * -1 means no namespace.
246 * >=+0 and FORM_UNQUALIFIED means that there IS a namespace,
247 * it just doesn't show up in the XML (but libxml2 will return it). */
248 const int ns_index;
249
250 /** Number of namespace URIs*/
251 const unsigned short nof_ns_uris;
252
253 /** List of namespace URIs
254 * In case of "anyElement" variants this list contains the valid ("anyElement from ...")
255 * or invalid ("anyElement except ...") namespace URIs.
256 * The unqualified namespace is marked by an empty string ("").*/
257 const char** ns_uris;
258};
259
af710487 260/** Information related to the embedded values in XML encoding
261 *
262 * Used when a record/set with the EMBED-VALUES coding instruction contains
263 * one or more record of/set of fields. */
264struct embed_values_enc_struct_t
265{
266#ifdef TITAN_RUNTIME_2
267 /** Stores the array of embedded values */
268 const Record_Of_Type* embval_array;
269 /** Stores the erroneous descriptor of the embedded values field (for negative tests) */
270 const Erroneous_descriptor_t* embval_err;
271 /** Error value index for the embedded values (for negative tests) */
272 int embval_err_val_idx;
273 /** Erroneous descriptor index for the embedded values (for negative tests) */
274 int embval_err_descr_idx;
275#else
276 /** Stores the array of embedded values as a Base_Type (use get_embedded_value
277 * to retrieve values - temporarily disabled) */
278 const Base_Type* embval_array;
279 /** Stores the size of the embedded value array */
280 int embval_size;
281#endif
282 /** Stores the index of the next embedded value to be read */
283 int embval_index;
284};
285
286/** Information related to the embedded values in XML decoding
287 *
288 * Used when a record/set with the EMBED-VALUES coding instruction contains
289 * one or more record of/set of fields. */
290struct embed_values_dec_struct_t
291{
292#ifdef TITAN_RUNTIME_2
293 /** Stores the array of embedded values */
294 Record_Of_Type* embval_array;
295#else
296 /** Stores the array of embedded values as a Base_type (use set_embedded_value
297 * to insert new values - temporarily disabled) */
298 Base_Type* embval_array;
299#endif
300 /** Stores the number of embedded values that are currently in the array,
301 * and the index where the next one should be inserted */
302 int embval_index;
303};
304
970ed795
EL
305/** Check the name of an XML node against a XER type descriptor.
306 *
307 * @param name the (local, unqualified) name of the XML element
308 * @param p_td the type descriptor
309 * @param exer \c true if Extended XER decoding, \c false for Basic and Canonical XER
310 * @return \c true if \p name corresponds to the type descriptor, \c false otherwise.
311 */
312inline bool check_name(const char *name, const XERdescriptor_t& p_td, int exer)
313{
314 return strncmp(name, p_td.names[exer], p_td.namelens[exer]-2) == 0
315 && name[p_td.namelens[exer]-2] == '\0';
316}
317
318/** Verify the namespace of an XML node against a XER type descriptor.
319 *
320 * @pre EXER decoding is in progress
321 *
322 * @param ns_uri the URI of the current node
323 * @param p_td the type descriptor
324 * @return \c true if \p ns_uri is NULL and the type has no namespace
325 * or it's the default namespace.
326 * @return \c true if \p ns_uri is not NULL and it matches the one referenced
327 * by \p p_td.
328 * @return \c false otherwise.
329 */
330bool check_namespace(const char *ns_uri, const XERdescriptor_t& p_td);
331
332/** Check that the current element matches the XER descriptor
333 *
334 * Calls TTCN_EncDec_ErrorContext::error() if it doesn't.
335 *
336 * @param reader XML reader
337 * @param p_td XER descriptor
338 * @param exer 0 for Basic/Canonical XER, 1 for EXER
339 * @return the name of the current element
340 */
341const char* verify_name(XmlReaderWrap& reader, const XERdescriptor_t& p_td, int exer);
342
343/** Check the end tag
344 *
345 * Calls verify_name(), then compares \a depth with the current XML depth
346 * and calls TTCN_EncDec_ErrorContext::error() if they don't match.
347 *
348 * @param reader XML reader
349 * @param p_td XER descriptor
350 * @param depth XML tag depth (0 for top-level element)
351 * @param exer 0 for Basic/Canonical XER, 1 for EXER
352 */
353void verify_end(XmlReaderWrap& reader, const XERdescriptor_t& p_td, const int depth, int exer);
354
355class TTCN_Buffer;
356
357/** Output the namespace prefix
358 *
359 * The namespace prefix is determined by the XER descriptor (@a my_module
360 * and @a ns_index fields). It is not written if p_td.xer_bits has
361 * FORM_UNQUALIFIED.
362 *
363 * @param p_td XER descriptor
364 * @param p_buf buffer to write into
365 *
366 * @pre the caller should check that E-XER encoding is in effect.
367 */
368void write_ns_prefix(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf);
369
370/** Output the beginning of an XML attribute.
371 *
372 * Writes a space, the attribute name (from \p p_td), and the string "='".
373 * @post the buffer is ready to receive the actual value
374 *
375 * @param p_td XER descriptor (contains the attribute name)
376 * @param p_buf buffer to write into
377 */
378inline void begin_attribute(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf)
379{
380 p_buf.put_c(' ');
381 write_ns_prefix(p_td, p_buf);
382 p_buf.put_s((size_t)p_td.namelens[1]-2, (const unsigned char*)p_td.names[1]);
383 p_buf.put_s((size_t)2, (const unsigned char*)"='");
384}
385
386/** Indent.
387 *
388 * @param buf buffer to write into.
389 * @param level indent level
390 *
391 * Writes the appropriate amount of indentation into \p buf.
392 *
393 * Indentation is currently done with with tabs.
394 * */
395int do_indent(TTCN_Buffer& buf, int level);
396
397/** Ensures that the anyElement or anyAttribute field respects its namespace
398 * restrictions.
399 * In case of "anyElement from ..." or "anyAttributes from ..." the namespace
400 * needs to be in the specified list.
401 * In case of "anyElement except ..." or "anyAttributes except ..." it cannot
402 * match any of the namespaces from the list.
403 * An invalid namespace causes a dynamic test case error.
404 *
405 * @param p_td type descriptor of the field in question, contains the list of
406 * valid or invalid namespaces
407 * @param p_xmlns constains the namespace in question
408 */
409void check_namespace_restrictions(const XERdescriptor_t& p_td, const char* p_xmlns);
410
411
412#ifdef DEFINE_XER_STRUCT
413# define XER_STRUCT2(type_name,xmlname) \
414 extern const XERdescriptor_t type_name##_xer_ = { \
415 { xmlname ">\n", xmlname ">\n" }, \
416 { 2+sizeof(xmlname)-1, 2+sizeof(xmlname)-1 }, \
417 0UL, WHITESPACE_PRESERVE, NULL, NULL, 0, 0, NULL }
418// The compiler should fold the two identical strings into one
419
420# define XER_STRUCT_COPY(cpy,original) \
421 const XERdescriptor_t& cpy##_xer_ = original##_xer_
422#else
423/** Declare a XER structure.
424 * @param type_name the name of a Titan runtime class
425 * @param xmlname the XML tag name
426 */
427# define XER_STRUCT2(type_name,xmlname) extern const XERdescriptor_t type_name##_xer_
428# define XER_STRUCT_COPY(cpy,original) extern const XERdescriptor_t& cpy##_xer_
429#endif
430
431/** Declare a XER structure where the name of the type matches the tag */
432# define XER_STRUCT(name) XER_STRUCT2(name, #name)
433
434/* XER descriptors for built-in types.
435 * The XML tag names are defined in Table 4, referenced by clause
436 * 11.25.2 (X.680/2002) or 12.36.2 (X.680/2008) */
437
438// Types shared between ASN.1 and TTCN-3
439XER_STRUCT2(BITSTRING, "BIT_STRING");
440XER_STRUCT (BOOLEAN);
441XER_STRUCT (CHARSTRING);
442XER_STRUCT2(FLOAT, "REAL");
443XER_STRUCT (INTEGER);
444XER_STRUCT2(OBJID, "OBJECT_IDENTIFIER");
445XER_STRUCT2(OCTETSTRING, "OCTET_STRING");
446XER_STRUCT (UNIVERSAL_CHARSTRING);
447
448XER_STRUCT(RELATIVE_OID);
449
450// ASN.1 types
451
452XER_STRUCT2(EMBEDDED_PDV, "SEQUENCE");
453XER_STRUCT2(EMBEDDED_PDV_identification, "identification");
454XER_STRUCT2(EMBEDDED_PDV_identification_sxs, "syntaxes");
455XER_STRUCT2(EMBEDDED_PDV_identification_sxs_abs, "abstract");
456XER_STRUCT2(EMBEDDED_PDV_identification_sxs_xfr, "transfer");
457XER_STRUCT2(EMBEDDED_PDV_identification_sx , "syntax");
458XER_STRUCT2(EMBEDDED_PDV_identification_pci, "presentation-context-id");
459XER_STRUCT2(EMBEDDED_PDV_identification_cn , "context-negotiation");
460XER_STRUCT2(EMBEDDED_PDV_identification_cn_pci , "presentation-context-id");
461XER_STRUCT2(EMBEDDED_PDV_identification_cn_tsx , "transfer-syntax");
462XER_STRUCT2(EMBEDDED_PDV_identification_ts , "transfer-syntax");
463XER_STRUCT2(EMBEDDED_PDV_identification_fix, "fixed");
464XER_STRUCT2(EMBEDDED_PDV_data_value_descriptor, "data-value-descriptor");
465XER_STRUCT2(EMBEDDED_PDV_data_value, "data-value");
466
467
468XER_STRUCT2(EXTERNAL, "SEQUENCE");
469XER_STRUCT2(EXTERNAL_direct_reference , "direct-reference");
470XER_STRUCT2(EXTERNAL_indirect_reference, "indirect-reference");
471XER_STRUCT2(EXTERNAL_data_value_descriptor, "data-value-descriptor");
472XER_STRUCT2(EXTERNAL_encoding, "encoding");
473XER_STRUCT2(EXTERNAL_encoding_singleASN , "single-ASN1-type");
474XER_STRUCT2(EXTERNAL_encoding_octet_aligned, "octet-aligned");
475XER_STRUCT2(EXTERNAL_encoding_arbitrary , "arbitrary");
476
477// The big, scary ASN.1 unrestricted character string
478XER_STRUCT2(CHARACTER_STRING, "SEQUENCE");
479XER_STRUCT_COPY(CHARACTER_STRING_identification, EMBEDDED_PDV_identification);
480XER_STRUCT_COPY(CHARACTER_STRING_identification_sxs, EMBEDDED_PDV_identification_sxs);
481XER_STRUCT_COPY(CHARACTER_STRING_identification_sxs_abs, EMBEDDED_PDV_identification_sxs_abs);
482XER_STRUCT_COPY(CHARACTER_STRING_identification_sxs_xfr, EMBEDDED_PDV_identification_sxs_xfr);
483XER_STRUCT_COPY(CHARACTER_STRING_identification_sx , EMBEDDED_PDV_identification_sx);
484XER_STRUCT_COPY(CHARACTER_STRING_identification_pci, EMBEDDED_PDV_identification_pci);
485XER_STRUCT_COPY(CHARACTER_STRING_identification_cn , EMBEDDED_PDV_identification_cn);
486XER_STRUCT_COPY(CHARACTER_STRING_identification_cn_pci , EMBEDDED_PDV_identification_cn_pci);
487XER_STRUCT_COPY(CHARACTER_STRING_identification_cn_tsx , EMBEDDED_PDV_identification_cn_tsx);
488XER_STRUCT_COPY(CHARACTER_STRING_identification_ts , EMBEDDED_PDV_identification_ts);
489XER_STRUCT_COPY(CHARACTER_STRING_identification_fix, EMBEDDED_PDV_identification_fix);
490// this one is used for decoding only (only to check that it's absent)
491XER_STRUCT2(CHARACTER_STRING_data_value_descriptor, "data-value-descriptor");
492// this can not be folded with EMBEDDED-PDV
493XER_STRUCT2(CHARACTER_STRING_data_value, "string-value");
494
495// ASN.1 restricted character strings
496XER_STRUCT(GeneralString);
497XER_STRUCT(NumericString);
498XER_STRUCT(UTF8String);
499XER_STRUCT(PrintableString);
500XER_STRUCT(UniversalString);
501
502XER_STRUCT(BMPString);
503XER_STRUCT(GraphicString);
504XER_STRUCT(IA5String);
505XER_STRUCT(TeletexString);
506XER_STRUCT(VideotexString);
507XER_STRUCT(VisibleString);
508
509XER_STRUCT2(ASN_NULL, "NULL");
510XER_STRUCT2(ASN_ROID, "RELATIVE_OID");
511XER_STRUCT (ASN_ANY); // obsoleted by 2002
512
513// TTCN-3 types
514XER_STRUCT2(HEXSTRING, "hexstring");
515XER_STRUCT2(VERDICTTYPE, "verdicttype");
516
517/** @} */
518
519#endif /*XER_HH_*/
This page took 0.082573 seconds and 5 git commands to generate.